2 * Glide64 - Glide video plugin for Nintendo 64 emulators.
3 * Copyright (c) 2002 Dave2001
4 * Copyright (c) 2008 Günther <guenther.emu@freenet.de>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 //****************************************************************
23 // Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
24 // Project started on December 29th, 2001
27 // * 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.
28 // * 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.
30 // Official Glide64 development channel: #Glide64 on EFnet
32 // Original author: Dave2001 (Dave2999@hotmail.com)
33 // Other authors: Gonetz, Gugaman
35 //****************************************************************
37 // Call this macro to automatically switch out of fullscreen, then break. :)
38 // useful for debugging fullscreen areas that can't otherwise be accessed
43 #define max(a,b) ((a) > (b) ? (a) : (b))
44 #define min(a,b) ((a) < (b) ? (a) : (b))
47 extern char out_buf
[2048];
49 extern BOOL capture_screen
;
50 extern char capture_path
[256];
52 extern DWORD frame_count
; // frame counter
54 #define MAX_CACHE 1024
55 #define MAX_TRI_CACHE 768 // this is actually # of vertices, not triangles
60 #define TEXMEM_2MB_EDGE 2097152
63 #define SUP_TEXMIRROR 0x00000001
66 #define CLIP_XMAX 0x00000001
67 #define CLIP_XMIN 0x00000002
68 #define CLIP_YMAX 0x00000004
69 #define CLIP_YMIN 0x00000008
70 #define CLIP_ZMIN 0x00000010
73 #define ZBUF_ENABLED 0x00000001
74 #define ZBUF_DECAL 0x00000002
75 #define ZBUF_COMPARE 0x00000004
76 #define ZBUF_UPDATE 0x00000008
77 #define ALPHA_COMPARE 0x00000010
78 #define FORCE_BL 0x00000020
79 #define CULL_FRONT 0x00001000 // * must be here
80 #define CULL_BACK 0x00002000 // * must be here
81 #define FOG_ENABLED 0x00010000
83 #define CULLMASK 0x00003000
87 #define UPDATE_ZBUF_ENABLED 0x00000001
89 #define UPDATE_TEXTURE 0x00000002 // \ Same thing!
90 #define UPDATE_COMBINE 0x00000002 // /
92 #define UPDATE_CULL_MODE 0x00000004
93 #define UPDATE_LIGHTS 0x00000010
94 #define UPDATE_BIASLEVEL 0x00000020
95 #define UPDATE_ALPHA_COMPARE 0x00000040
96 #define UPDATE_VIEWPORT 0x00000080
97 #define UPDATE_MULT_MAT 0x00000100
98 #define UPDATE_SCISSOR 0x00000200
99 #define UPDATE_FOG_ENABLED 0x00010000
101 #define CMB_MULT 0x00000001
102 #define CMB_SET 0x00000002
103 #define CMB_SUB 0x00000004
104 #define CMB_ADD 0x00000008
105 #define CMB_A_MULT 0x00000010
106 #define CMB_A_SET 0x00000020
107 #define CMB_A_SUB 0x00000040
108 #define CMB_A_ADD 0x00000080
109 #define CMB_SETSHADE_SHADEALPHA 0x00000100
110 #define CMB_INTER 0x00000200
111 #define CMB_MULT_OWN_ALPHA 0x00000400
112 #define CMB_COL_SUB_OWN 0x00000800
114 #define uc(x) coord[x<<1]
115 #define vc(x) coord[(x<<1)+1]
121 float u0
, v0
, u1
, v1
;
126 BYTE b
; // These values are arranged like this so that *(DWORD*)(VERTEX+?) is
127 BYTE g
; // ARGB format that glide can use.
133 float vec
[3]; // normal vector
136 float x_w
, y_w
, z_w
, u0_w
, v0_w
, u1_w
, v1_w
, oow
;
138 BYTE screen_translated
;
139 BYTE shade_mods_allowed
;
141 DWORD uv_calculated
; // like crc
145 int number
; // way to identify it
146 int scr_off
, z_off
; // off the screen?
149 // Clipping (scissors)
160 DWORD res_x
, scr_res_x
;
161 DWORD res_y
, scr_res_y
;
162 DWORD res_data
, res_data_org
;
164 BOOL autodetect_ucode
;
196 BOOL noditheredalpha
;
202 //Frame buffer emulation options
208 BOOL fb_hires_buf_clear
;
210 BOOL fb_depth_render
;
211 BOOL fb_optimize_texrect
;
212 BOOL fb_optimize_write
;
213 BOOL fb_ignore_aux_copy
;
214 BOOL fb_ignore_previous
;
218 int offset_x
, offset_y
;
219 int scale_x
, scale_y
;
223 BOOL flame_corona
; //hack for zeldas flame's corona
226 BOOL soft_depth_compare
; // use GR_CMP_LEQUAL instead of GR_CMP_LESS
227 BOOL increase_texrect_edge
; // add 1 to lower right corner coordinates of texrect
228 BOOL decrease_fillrect_edge
; // sub 1 from lower right corner coordinates of fillrect
229 int stipple_mode
; //used for dithered alpha emulation
230 DWORD stipple_pattern
; //used for dithered alpha emulation
231 BOOL force_microcheck
; //check microcode each frame, for mixed F3DEX-S2DEX games
237 BOOL force_depth_compare
; //NFL Quarterback Club 99 and All-Star Baseball 2000
238 BOOL fillcolor_fix
; //use first part of fillcolor in fillrects
239 BOOL cpu_write_hack
; //show images writed directly by CPU
240 BOOL increase_primdepth
; //increase prim_depth value for texrects
242 BOOL zelda
; //zeldas hacks
243 BOOL bomberman64
; //bomberman64 hacks
244 BOOL diddy
; //diddy kong racing
245 BOOL tonic
; //tonic trouble
246 BOOL PPL
; //pokemon puzzle league requires many special fixes
247 BOOL ASB
; //All-Star Baseball games
248 BOOL doraemon2
;//Doraemon 2
249 BOOL invaders
; //Space Invaders
250 BOOL BAR
; //Beetle Adventure Racing
251 BOOL ISS64
; //International Superstar Soccer 64
252 BOOL RE2
; //Resident Evil 2
253 BOOL nitro
; //WCW Nitro
254 BOOL chopper
; //Chopper Attack
255 BOOL yoshi
; // Yoshi Story
256 BOOL fzero
; // F-Zero
257 BOOL PM
; //Paper Mario
258 BOOL TGR
; //Top Gear Rally
259 BOOL TGR2
; //Top Gear Rally 2
260 BOOL KI
; //Killer Instinct
261 BOOL lego
; //LEGO Racers
272 // This structure is what is passed in by rdp:settextureimage
274 BYTE format
; // format: ARGB, IA, ...
275 BYTE size
; // size: 4,8,16, or 32 bit
276 WORD width
; // used in settextureimage
277 DWORD addr
; // address in RDRAM to load the texture from
278 BOOL set_by
; // 0-loadblock 1-loadtile
281 // This structure is a tile descriptor (as used by rdp:settile and rdp:settilesize)
285 BYTE format
; // format: ARGB, IA, ...
286 BYTE size
; // size: 4,8,16, or 32 bit
287 WORD line
; // size of one row (x axis) in 64 bit words
288 WORD t_mem
; // location in texture memory (in 64 bit words, max 512 (4MB))
289 BYTE palette
; // palette # to use
290 BYTE clamp_t
; // clamp or wrap (y axis)?
291 BYTE mirror_t
; // mirroring on (y axis)?
292 BYTE mask_t
; // mask to wrap around (ex: 5 would wrap around 32) (y axis)
293 BYTE shift_t
; // ??? (scaling)
294 BYTE clamp_s
; // clamp or wrap (x axis)?
295 BYTE mirror_s
; // mirroring on (x axis)?
296 BYTE mask_s
; // mask to wrap around (x axis)
297 BYTE shift_s
; // ??? (scaling)
299 DWORD hack
; // any hacks needed
302 WORD ul_s
; // upper left s coordinate
303 WORD ul_t
; // upper left t coordinate
304 WORD lr_s
; // lower right s coordinate
305 WORD lr_t
; // lower right t coordinate
310 // these are set by loadtile
311 WORD t_ul_s
; // upper left s coordinate
312 WORD t_ul_t
; // upper left t coordinate
313 WORD t_lr_s
; // lower right s coordinate
314 WORD t_lr_t
; // lower right t coordinate
328 // This structure forms the lookup table for cached textures
330 DWORD addr
; // address in RDRAM
331 DWORD crc
; // CRC check
332 DWORD palette
; // Palette #
333 DWORD width
; // width
334 DWORD height
; // height
335 DWORD format
; // format
337 DWORD last_used
; // what frame # was this texture last used (used for replacing)
341 DWORD flags
; // clamp/wrap/mirror flags
343 DWORD realwidth
; // width of actual texture
344 DWORD realheight
; // height of actual texture
351 float scale_x
; // texture scaling
353 float scale
; // general scale to 256
355 GrTexInfo t_info
; // texture info (glide)
356 DWORD tmem_addr
; // addres in texture memory (glide)
358 int uses
; // 1 triangle that uses this texture
360 int splits
; // number of splits
363 float c_off
; // ul center texel offset (both x and y)
364 float c_scl_x
; // scale to lower-right center-texel x
365 float c_scl_y
; // scale to lower-right center-texel y
367 DWORD mod
, mod_color
, mod_color1
, mod_color2
, mod_factor
;
373 float r
, g
, b
, a
; // color
374 float dir_x
, dir_y
, dir_z
; // direction towards the light source
375 float x
, y
, z
, w
; // light position
388 ci_main
, //0, main color image
389 ci_zimg
, //1, depth image
390 ci_unknown
, //2, status is unknown
391 ci_useless
, //3, status is unclear
392 ci_old_copy
, //4, auxilary color image, copy of last color image from previous frame
393 ci_copy
, //5, auxilary color image, copy of previous color image
394 ci_copy_self
, //6, main color image, it's content will be used to draw into itself
395 ci_zcopy
, //7, auxilary color image, copy of depth image
396 ci_aux
, //8, auxilary color image
397 ci_aux_copy
//9, auxilary color image, partial copy of previous color image
403 DWORD addr
; //color image address
415 DWORD addr
; //address of color image
417 DWORD tex_addr
; //address in video memory
418 DWORD width
; //width of color image
419 DWORD height
; //height of color image
420 WORD format
; //format of color image
421 BOOL clear
; //flag. texture buffer must be cleared
422 BOOL drawn
; //flag. if equal to 1, this image was already drawn in current frame
423 float scr_width
; //width of rendered image
424 float scr_height
; //height of rendered image
425 DWORD tex_width
; //width of texture buffer
426 DWORD tex_height
; //height of texture buffer
428 WORD tile_uls
; //shift from left bound of the texture
429 WORD tile_ult
; //shift from top of the texture
430 DWORD v_shift
; //shift from top of the texture
431 DWORD u_shift
; //shift from left of the texture
432 float u_scale
; //used to map vertex u,v coordinates into hires texture
433 float v_scale
; //used to map vertex u,v coordinates into hires texture
440 DWORD begin
; //start of the block in video memory
441 DWORD end
; //end of the block in video memory
442 BYTE count
; //number of allocated texture buffers
443 BOOL clear_allowed
; //stack of buffers can be cleared
444 HIRES_COLOR_IMAGE images
[256];
456 float offset_x
, offset_y
;
458 float scale_x
, scale_1024
, scale_x_bak
;
459 float scale_y
, scale_768
, scale_y_bak
;
469 DWORD tri_n
; // triangle counter
473 DWORD pc
[10]; // DList PC stack
474 DWORD pc_i
; // current PC index in the stack
475 int dl_count
; // number of instructions before returning
478 DWORD segment
[16]; // Segment pointer
480 // Marks the end of DList execution (done in uc?:enddl)
499 DWORD prim_lodmin
, prim_lodfrac
;
504 float col
[4]; // color multiplier
505 float coladd
[4]; // color add/subtract
510 DWORD cmb_flags
, cmb_flags_2
;
513 int acmp
; // 0 = none, 1 = threshold, 2 = dither
514 int zsrc
; // 0 = pixel, 1 = prim
517 int clip
; // clipping flags
518 VERTEX vtx1
[256]; // copy vertex buffer #1 (used for clipping)
519 VERTEX vtx2
[256]; // copy vertex buffer #2
520 VERTEX
*vtxbuf
; // current vertex buffer (reset to vtx, used to determine current
523 int n_global
; // Used to pass the number of vertices from clip_z to clip_tri
528 __declspec( align(16) ) float model
[4][4];
529 __declspec( align(16) ) float proj
[4][4];
530 __declspec( align(16) ) float combined
[4][4];
531 __declspec( align(16) ) float dkrproj
[3][4][4];
533 __declspec( align(16) ) float model_stack
[32][4][4]; // 32 deep, will warn if overflow
534 int model_i
; // index in the model matrix stack
535 int model_stack_size
;
538 TEXTURE_IMAGE timg
; // 1 for each tmem address
539 TILE tiles
[8]; // 8 tile descriptors
540 BYTE tmem
[4096]; // 4k tmem
541 DWORD addr
[512]; // 512 addresses (used to determine address loaded from)
543 int cur_tile
; // current tile
545 int last_tile
; // last tile set
546 int last_tile_size
; // last tile size set
548 CACHE_LUT cache
[MAX_TMU
][MAX_CACHE
];
549 CACHE_LUT
*cur_cache
[2];
550 DWORD cur_cache_n
[2];
551 int n_cached
[MAX_TMU
];
552 DWORD tmem_ptr
[MAX_TMU
];
555 int best_tex
; // if no 2-tmus, which texture? (0 or 1)
569 float light_vector
[12][3];
574 DWORD cycle1
, cycle2
, cycle_mode
;
575 BYTE c_a0
, c_b0
, c_c0
, c_d0
, c_Aa0
, c_Ab0
, c_Ac0
, c_Ad0
;
576 BYTE c_a1
, c_b1
, c_c1
, c_d1
, c_Aa1
, c_Ab1
, c_Ac1
, c_Ad1
;
578 BYTE fbl_a0
, fbl_b0
, fbl_c0
, fbl_d0
;
579 BYTE fbl_a1
, fbl_b1
, fbl_c1
, fbl_d1
;
581 BYTE uncombined
; // which is uncombined: 0x01=color 0x02=alpha 0x03=both
583 // float YUV_C0, YUV_C1, YUV_C2, YUV_C3, YUV_C4; //YUV textures conversion coefficients
585 float yuv_ul_x
, yuv_ul_y
, yuv_lr_x
, yuv_lr_y
;
588 // What needs updating
598 DWORD tex_ctr
; // same as above, incremented every time textures are updated
600 BOOL allow_combine
; // allow combine updating?
602 BOOL s2dex_tex_loaded
;
605 DWORD rm
; // use othermode_l instead, this just as a check for changes
606 DWORD render_mode_changed
;
612 // used to check if in texrect while loading texture
615 //frame buffer related slots. Added by Gonetz
616 COLOR_IMAGE frame_buffers
[NUMTEXBUF
+2];
617 DWORD cimg
, ocimg
, zimg
, tmpzimg
, vi_org_reg
;
618 COLOR_IMAGE maincimg
[2];
619 DWORD last_drawn_ci_addr
;
620 DWORD main_ci
, main_ci_end
, main_ci_bg
, main_ci_last_tex_addr
, zimg_end
, last_bg
;
621 DWORD ci_width
, ci_height
, ci_size
, ci_end
;
624 BYTE ci_count
, num_of_ci
, main_ci_index
, copy_ci_index
;
625 int swap_ci_index
, black_ci_index
;
626 DWORD ci_upper_bound
, ci_lower_bound
;
627 BOOL motionblur
, fb_drawn
, fb_drawn_front
, read_previous_ci
, read_whole_frame
;
629 TEXTURE_BUFFER texbufs
[2];
630 HIRES_COLOR_IMAGE
* cur_image
; //image currently being drawn
631 HIRES_COLOR_IMAGE
* hires_tex
; //image, which corresponds to currently selected texture
634 BOOL skip_drawing
; //rendering is not required. used for frame buffer emulation
636 //fog related slots. Added by Gonetz
637 float fog_multiplier
, fog_offset
;
638 BOOL fog_coord_enabled
;
643 void SetWireframeCol ();
647 extern SETTINGS settings
;
648 extern HOTKEY_INFO hotkey_info
;
650 extern GrTexInfo fontTex
;
651 extern GrTexInfo cursorTex
;
652 extern DWORD offset_font
;
653 extern DWORD offset_cursor
;
654 extern DWORD offset_textures
;
655 extern DWORD offset_texbuf1
;
657 extern BOOL ucode_error_report
;
663 extern const char *ACmp
[4];
664 extern const char *Mode0
[16];
665 extern const char *Mode1
[16];
666 extern const char *Mode2
[32];
667 extern const char *Mode3
[8];
668 extern const char *Alpha0
[8];
669 extern const char *Alpha2
[8];
670 extern const char *str_zs
[2];
671 extern const char *str_yn
[2];
672 extern const char *str_offon
[2];
673 extern const char *str_cull
[4];
674 extern const char *str_format
[8];
675 extern const char *str_size
[4];
676 extern const char *str_cm
[4];
677 extern const char *str_filter
[3];
678 extern const char *str_tlut
[4];
679 extern const char *CIStatus
[10];
681 #define Alpha1 Alpha0
682 #define Alpha3 Alpha0
688 // Convert from u0/v0/u1/v1 to the real coordinates without regard to tmu
689 __inline
void ConvertCoordsKeep (VERTEX
*v
, int n
)
691 for (int i
=0; i
<n
; i
++)
693 v
[i
].uc(0) = v
[i
].u0
;
694 v
[i
].vc(0) = v
[i
].v0
;
695 v
[i
].uc(1) = v
[i
].u1
;
696 v
[i
].vc(1) = v
[i
].v1
;
700 // Convert from u0/v0/u1/v1 to the real coordinates based on the tmu they are on
701 __inline
void ConvertCoordsConvert (VERTEX
*v
, int n
)
704 if (rdp
.hires_tex
&& rdp
.tex
!= 3)
706 for (int i
=0; i
<n
; i
++)
714 for (int i
=0; i
<n
; i
++)
716 v
[i
].uc(rdp
.t0
) = v
[i
].u0
;
717 v
[i
].vc(rdp
.t0
) = v
[i
].v0
;
718 v
[i
].uc(rdp
.t1
) = v
[i
].u1
;
719 v
[i
].vc(rdp
.t1
) = v
[i
].v1
;
723 __inline
void AllowShadeMods (VERTEX
*v
, int n
)
725 for (int i
=0; i
<n
; i
++)
727 v
[i
].shade_mods_allowed
= 1;
731 __inline
float ScaleZ(float z
)
734 // if (z > 65535.0f) return 65535.0f;
735 // return (z / 65535.0f) * z;
736 // if (z < 4096.0f) return z * 0.25f;
737 // z = (z / 16384.0f) * z;
739 if (z
> 65534.0f
) return 65534.0f
;
743 __inline
void CalculateFog (VERTEX
*v
)
745 if (rdp
.flags
& FOG_ENABLED
)
747 v
->f
= min(255.0f
, max(0.0f
, v
->z_w
* rdp
.fog_multiplier
+ rdp
.fog_offset
));
756 void newSwapBuffers();
759 // ** utility functions
760 void load_palette (DWORD addr
, WORD start
, WORD count
);
762 #endif // ifndef RDP_H