/* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2008 Günther * * This program is free software; you can redistribute it and/or modify * 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 * Licence along with this program; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64) // Project started on December 29th, 2001 // // 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. // // Official Glide64 development channel: #Glide64 on EFnet // // Original author: Dave2001 (Dave2999@hotmail.com) // Other authors: Gonetz, Gugaman // //**************************************************************** // Call this macro to automatically switch out of fullscreen, then break. :) // useful for debugging fullscreen areas that can't otherwise be accessed #ifndef RDP_H #define RDP_H #ifdef GCC #define max(a,b) ((a) > (b) ? (a) : (b)) #define min(a,b) ((a) < (b) ? (a) : (b)) #endif extern char out_buf[2048]; extern BOOL capture_screen; extern char capture_path[256]; extern DWORD frame_count; // frame counter #define MAX_CACHE 1024 #define MAX_TRI_CACHE 768 // this is actually # of vertices, not triangles #define MAX_VTX 256 #define MAX_TMU 2 #define TEXMEM_2MB_EDGE 2097152 // 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_ZMIN 0x00000010 // Flags #define ZBUF_ENABLED 0x00000001 #define ZBUF_DECAL 0x00000002 #define ZBUF_COMPARE 0x00000004 #define ZBUF_UPDATE 0x00000008 #define ALPHA_COMPARE 0x00000010 #define FORCE_BL 0x00000020 #define CULL_FRONT 0x00001000 // * must be here #define CULL_BACK 0x00002000 // * must be here #define FOG_ENABLED 0x00010000 #define CULLMASK 0x00003000 #define CULLSHIFT 12 // Update flags #define UPDATE_ZBUF_ENABLED 0x00000001 #define UPDATE_TEXTURE 0x00000002 // \ Same thing! #define UPDATE_COMBINE 0x00000002 // / #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 #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 #define uc(x) coord[x<<1] #define vc(x) coord[(x<<1)+1] // Vertex structure typedef struct { float x, y, z, q; float u0, v0, u1, v1; float coord[4]; float w; WORD flags; BYTE b; // These values are arranged like this so that *(DWORD*)(VERTEX+?) is BYTE g; // ARGB format that glide can use. BYTE r; BYTE a; float f; //fog float vec[3]; // normal vector float sx, sy, sz; float x_w, y_w, z_w, u0_w, v0_w, u1_w, v1_w, oow; BYTE not_zclipped; BYTE screen_translated; BYTE shade_mods_allowed; BYTE uv_fixed; DWORD uv_calculated; // like crc float ou, ov; int number; // way to identify it int scr_off, z_off; // off the screen? } VERTEX; // Clipping (scissors) typedef struct { DWORD ul_x; DWORD ul_y; DWORD lr_x; DWORD lr_y; } SCISSOR; typedef struct { BYTE card_id; DWORD res_x, scr_res_x; DWORD res_y, scr_res_y; DWORD res_data, res_data_org; BOOL autodetect_ucode; DWORD ucode; BOOL wireframe; int wfmode; int lodmode; BYTE filtering; BOOL fog; BOOL buff_clear; // BOOL clear_8; BOOL vsync; BOOL fast_crc; BYTE swapmode; BOOL logging; BOOL elogging; BOOL log_clear; BOOL filter_cache; BOOL unk_as_red; BOOL log_unk; BOOL unk_clear; BYTE show_fps; BOOL clock; BOOL clock_24_hr; #ifndef _WIN32 DWORD full_res; DWORD tex_filter; BOOL noditheredalpha; BOOL noglsl; BOOL FBO; BOOL disable_auxbuf; #endif // _WIN32 //Frame buffer emulation options BOOL fb_read_always; BOOL fb_read_alpha; BOOL fb_smart; BOOL fb_motionblur; BOOL fb_hires; BOOL fb_hires_buf_clear; BOOL fb_depth_clear; BOOL fb_depth_render; BOOL fb_optimize_texrect; BOOL fb_optimize_write; BOOL fb_ignore_aux_copy; BOOL fb_ignore_previous; BOOL fb_get_info; // Special fixes int offset_x, offset_y; int scale_x, scale_y; BOOL alt_tex_size; BOOL use_sts1_only; BOOL wrap_big_tex; BOOL flame_corona; //hack for zeldas flame's corona int fix_tex_coord; int depth_bias; BOOL soft_depth_compare; // use GR_CMP_LEQUAL instead of GR_CMP_LESS BOOL increase_texrect_edge; // add 1 to lower right corner coordinates of texrect BOOL decrease_fillrect_edge; // sub 1 from lower right corner coordinates of fillrect int stipple_mode; //used for dithered alpha emulation DWORD stipple_pattern; //used for dithered alpha emulation BOOL force_microcheck; //check microcode each frame, for mixed F3DEX-S2DEX games BOOL custom_ini; BOOL hotkeys; //Special game hacks BOOL force_depth_compare; //NFL Quarterback Club 99 and All-Star Baseball 2000 BOOL fillcolor_fix; //use first part of fillcolor in fillrects BOOL cpu_write_hack; //show images writed directly by CPU BOOL increase_primdepth; //increase prim_depth value for texrects BOOL zelda; //zeldas hacks BOOL bomberman64; //bomberman64 hacks BOOL diddy; //diddy kong racing BOOL tonic; //tonic trouble BOOL PPL; //pokemon puzzle league requires many special fixes BOOL ASB; //All-Star Baseball games BOOL doraemon2;//Doraemon 2 BOOL invaders; //Space Invaders BOOL BAR; //Beetle Adventure Racing BOOL ISS64; //International Superstar Soccer 64 BOOL RE2; //Resident Evil 2 BOOL nitro; //WCW Nitro BOOL chopper; //Chopper Attack BOOL yoshi; // Yoshi Story BOOL fzero; // F-Zero BOOL PM; //Paper Mario BOOL TGR; //Top Gear Rally BOOL TGR2; //Top Gear Rally 2 BOOL KI; //Killer Instinct BOOL lego; //LEGO Racers } SETTINGS; typedef struct { BYTE fb_always; BYTE fb_motionblur; BYTE filtering; BYTE corona; } HOTKEY_INFO; // This structure is what is passed in by rdp:settextureimage typedef struct { BYTE format; // format: ARGB, IA, ... BYTE size; // size: 4,8,16, or 32 bit WORD width; // used in settextureimage DWORD addr; // address in RDRAM to load the texture from BOOL 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:settile BYTE format; // format: ARGB, IA, ... BYTE size; // size: 4,8,16, or 32 bit WORD line; // size of one row (x axis) in 64 bit words WORD t_mem; // location in texture memory (in 64 bit words, max 512 (4MB)) BYTE palette; // palette # to use BYTE clamp_t; // clamp or wrap (y axis)? BYTE mirror_t; // mirroring on (y axis)? BYTE mask_t; // mask to wrap around (ex: 5 would wrap around 32) (y axis) BYTE shift_t; // ??? (scaling) BYTE clamp_s; // clamp or wrap (x axis)? BYTE mirror_s; // mirroring on (x axis)? BYTE mask_s; // mask to wrap around (x axis) BYTE shift_s; // ??? (scaling) DWORD hack; // any hacks needed // rdp:settilesize WORD ul_s; // upper left s coordinate WORD ul_t; // upper left t coordinate WORD lr_s; // lower right s coordinate WORD lr_t; // lower right t coordinate float f_ul_s; float f_ul_t; // these are set by loadtile WORD t_ul_s; // upper left s coordinate WORD t_ul_t; // upper left t coordinate WORD t_lr_s; // lower right s coordinate WORD t_lr_t; // lower right t coordinate DWORD width; DWORD height; // uc0:texture BYTE on; float s_scale; float t_scale; WORD org_s_scale; WORD org_t_scale; } TILE; // This structure forms the lookup table for cached textures typedef struct { DWORD addr; // address in RDRAM DWORD crc; // CRC check DWORD palette; // Palette # DWORD width; // width DWORD height; // height DWORD format; // format DWORD size; // size DWORD last_used; // what frame # was this texture last used (used for replacing) DWORD line; DWORD flags; // clamp/wrap/mirror flags DWORD realwidth; // width of actual texture DWORD realheight; // height of actual texture DWORD lod; DWORD aspect; BOOL set_by; DWORD texrecting; float scale_x; // texture scaling float scale_y; float scale; // general scale to 256 GrTexInfo t_info; // texture info (glide) DWORD tmem_addr; // addres in texture memory (glide) int uses; // 1 triangle that uses this texture int splits; // number of splits 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 DWORD mod, mod_color, mod_color1, mod_color2, mod_factor; } CACHE_LUT; // Lights typedef struct { float r, g, b, a; // color float dir_x, dir_y, dir_z; // direction towards the light source float x, y, z, w; // light position float ca, la, qa; DWORD nonblack; DWORD nonzero; } LIGHT; typedef enum { noise_none, noise_combine, noise_texture } NOISE_MODE; 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, auxilary color image, copy of last color image from previous frame ci_copy, //5, auxilary 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, auxilary color image, copy of depth image ci_aux, //8, auxilary color image ci_aux_copy //9, auxilary color image, partial copy of previous color image } CI_STATUS; // Frame buffers typedef struct { DWORD addr; //color image address DWORD format; DWORD size; DWORD width; DWORD height; CI_STATUS status; int changed; } COLOR_IMAGE; typedef struct { GrChipID_t tmu; DWORD addr; //address of color image DWORD end_addr; DWORD tex_addr; //address in video memory DWORD width; //width of color image DWORD height; //height of color image WORD format; //format of color image BOOL clear; //flag. texture buffer must be cleared BOOL drawn; //flag. if equal to 1, this image was already drawn in current frame float scr_width; //width of rendered image float scr_height; //height of rendered image DWORD tex_width; //width of texture buffer DWORD tex_height; //height of texture buffer int tile; // WORD tile_uls; //shift from left bound of the texture WORD tile_ult; //shift from top of the texture DWORD v_shift; //shift from top of the texture DWORD u_shift; //shift from left of the texture 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 GrTexInfo info; } HIRES_COLOR_IMAGE; typedef struct { GrChipID_t tmu; DWORD begin; //start of the block in video memory DWORD end; //end of the block in video memory BYTE count; //number of allocated texture buffers BOOL clear_allowed; //stack of buffers can be cleared HIRES_COLOR_IMAGE images[256]; } TEXTURE_BUFFER; #define NUMTEXBUF 92 typedef struct { float vi_width; float vi_height; BOOL window_changed; float offset_x, offset_y; float scale_x, scale_1024, scale_x_bak; float scale_y, scale_768, scale_y_bak; DWORD res_scale_x; DWORD res_scale_y; float view_scale[3]; float view_trans[3]; BOOL updatescreen; DWORD tri_n; // triangle counter DWORD debug_n; // Program counter DWORD pc[10]; // DList PC stack DWORD pc_i; // current PC index in the stack int dl_count; // number of instructions before returning // Segments DWORD segment[16]; // Segment pointer // Marks the end of DList execution (done in uc?:enddl) int halt; // Next command DWORD cmd0; DWORD cmd1; DWORD cmd2; DWORD cmd3; // Clipping SCISSOR scissor_o; SCISSOR scissor; // Colors DWORD fog_color; DWORD fill_color; DWORD prim_color; DWORD blend_color; DWORD env_color; DWORD prim_lodmin, prim_lodfrac; WORD prim_depth; BYTE K5; NOISE_MODE noise; float col[4]; // color multiplier float coladd[4]; // color add/subtract float shade_factor; float col_2[4]; DWORD cmb_flags, cmb_flags_2; // othermode_l flags int acmp; // 0 = none, 1 = threshold, 2 = dither int zsrc; // 0 = pixel, 1 = prim // 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; // Matrices __declspec( align(16) ) float model[4][4]; __declspec( align(16) ) float proj[4][4]; __declspec( align(16) ) float combined[4][4]; __declspec( align(16) ) float dkrproj[3][4][4]; __declspec( align(16) ) float 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 BYTE tmem[4096]; // 4k tmem DWORD 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 CACHE_LUT cache[MAX_TMU][MAX_CACHE]; CACHE_LUT *cur_cache[2]; DWORD cur_cache_n[2]; int n_cached[MAX_TMU]; DWORD tmem_ptr[MAX_TMU]; int t0, t1; int best_tex; // if no 2-tmus, which texture? (0 or 1) int tex; int filter_mode; // Texture palette WORD pal_8[256]; DWORD pal_8_crc[16]; DWORD pal_256_crc; BYTE tlut_mode; BOOL LOD_en; // Lighting DWORD num_lights; LIGHT light[12]; float light_vector[12][3]; float lookat[2][3]; BOOL use_lookat; // Combine modes DWORD cycle1, cycle2, cycle_mode; BYTE c_a0, c_b0, c_c0, c_d0, c_Aa0, c_Ab0, c_Ac0, c_Ad0; BYTE c_a1, c_b1, c_c1, c_d1, c_Aa1, c_Ab1, c_Ac1, c_Ad1; BYTE fbl_a0, fbl_b0, fbl_c0, fbl_d0; BYTE fbl_a1, fbl_b1, fbl_c1, fbl_d1; BYTE uncombined; // which is uncombined: 0x01=color 0x02=alpha 0x03=both // float YUV_C0, YUV_C1, YUV_C2, YUV_C3, YUV_C4; //YUV textures conversion coefficients BOOL yuv_image; float yuv_ul_x, yuv_ul_y, yuv_lr_x, yuv_lr_y; DWORD yuv_im_begin; // What needs updating DWORD update; DWORD flags; BOOL first; // Vertices VERTEX vtx[MAX_VTX]; int v0, vn; DWORD tex_ctr; // same as above, incremented every time textures are updated BOOL allow_combine; // allow combine updating? BOOL s2dex_tex_loaded; // Debug stuff DWORD rm; // use othermode_l instead, this just as a check for changes DWORD render_mode_changed; DWORD geom_mode; DWORD othermode_h; DWORD othermode_l; // used to check if in texrect while loading texture DWORD texrecting; //frame buffer related slots. Added by Gonetz COLOR_IMAGE frame_buffers[NUMTEXBUF+2]; DWORD cimg, ocimg, zimg, tmpzimg, vi_org_reg; COLOR_IMAGE maincimg[2]; DWORD last_drawn_ci_addr; DWORD main_ci, main_ci_end, main_ci_bg, main_ci_last_tex_addr, zimg_end, last_bg; DWORD ci_width, ci_height, ci_size, ci_end; DWORD zi_width; int zi_lrx, zi_lry; BYTE ci_count, num_of_ci, main_ci_index, copy_ci_index; int swap_ci_index, black_ci_index; DWORD ci_upper_bound, ci_lower_bound; BOOL motionblur, fb_drawn, fb_drawn_front, read_previous_ci, read_whole_frame; CI_STATUS ci_status; TEXTURE_BUFFER texbufs[2]; HIRES_COLOR_IMAGE * cur_image; //image currently being drawn HIRES_COLOR_IMAGE * hires_tex; //image, which corresponds to currently selected texture BYTE cur_tex_buf; BYTE acc_tex_buf; BOOL skip_drawing; //rendering is not required. used for frame buffer emulation //fog related slots. Added by Gonetz float fog_multiplier, fog_offset; BOOL fog_coord_enabled; } RDP; void SetWireframeCol (); void ChangeSize (); extern RDP rdp; extern SETTINGS settings; extern HOTKEY_INFO hotkey_info; extern GrTexInfo fontTex; extern GrTexInfo cursorTex; extern DWORD offset_font; extern DWORD offset_cursor; extern DWORD offset_textures; extern DWORD offset_texbuf1; extern BOOL ucode_error_report; // RDP functions void rdp_reset (); // global strings extern const char *ACmp[4]; extern const char *Mode0[16]; extern const char *Mode1[16]; extern const char *Mode2[32]; extern const char *Mode3[8]; extern const char *Alpha0[8]; extern const char *Alpha2[8]; extern const char *str_zs[2]; extern const char *str_yn[2]; extern const char *str_offon[2]; extern const char *str_cull[4]; extern const char *str_format[8]; extern const char *str_size[4]; extern const char *str_cm[4]; extern const char *str_filter[3]; extern const char *str_tlut[4]; extern const char *CIStatus[10]; #define Alpha1 Alpha0 #define Alpha3 Alpha0 #define FBL_D_1 2 #define FBL_D_0 3 // Convert from u0/v0/u1/v1 to the real coordinates without regard to tmu __inline void ConvertCoordsKeep (VERTEX *v, int n) { for (int i=0; i 65535.0f) return 65535.0f; // return (z / 65535.0f) * z; // if (z < 4096.0f) return z * 0.25f; // z = (z / 16384.0f) * z; z *= 1.9f; if (z > 65534.0f) return 65534.0f; return z; } __inline void CalculateFog (VERTEX *v) { if (rdp.flags & FOG_ENABLED) { v->f = min(255.0f, max(0.0f, v->z_w * rdp.fog_multiplier + rdp.fog_offset)); v->a = (BYTE)v->f; } else { v->f = 1.0f; } } void newSwapBuffers(); extern BOOL SwapOK; // ** utility functions void load_palette (DWORD addr, WORD start, WORD count); #endif // ifndef RDP_H