Path: blob/master/libmupen64plus/mupen64plus-video-glide64mk2/src/Glide64/Main.cpp
2 views
/*1* Glide64 - Glide video plugin for Nintendo 64 emulators.2* Copyright (c) 2002 Dave20013* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License as published by7* the Free Software Foundation; either version 2 of the License, or8* any later version.9*10* This program is distributed in the hope that it will be useful,11* but WITHOUT ANY WARRANTY; without even the implied warranty of12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13* GNU General Public License for more details.14*15* You should have received a copy of the GNU General Public License16* along with this program; if not, write to the Free Software17* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA18*/1920//****************************************************************21//22// Glide64 - Glide Plugin for Nintendo 64 emulators23// Project started on December 29th, 200124//25// Authors:26// Dave2001, original author, founded the project in 2001, left it in 200227// Gugaman, joined the project in 2002, left it in 200228// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 200229// Hiroshi 'KoolSmoky' Morii, joined the project in 200730//31//****************************************************************32//33// To modify Glide64:34// * 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.35// * 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.36//37//****************************************************************3839#include "Gfx_1.3.h"40#include "Config.h"41#include "Util.h"42#include "3dmath.h"43#include "Debugger.h"44#include "Combine.h"45#include "TexCache.h"46#include "CRC.h"47#include "FBtoScreen.h"48#include "DepthBufferRender.h"4950#if defined(__GNUC__)51#include <sys/time.h>52#elif defined(__MSC__)53#include <time.h>54#define PATH_MAX MAX_PATH55#endif56#include "osal_dynamiclib.h"57#ifdef TEXTURE_FILTER // Hiroshi Morii <[email protected]>58#include <stdarg.h>59int ghq_dmptex_toggle_key = 0;60#endif61#if defined(__MINGW32__)62#define swprintf _snwprintf63#define vswprintf _vsnwprintf64#endif6566#define G64_VERSION "G64 Mk2"67#define RELTIME "Date: " __DATE__// " Time: " __TIME__6869#ifdef EXT_LOGGING70std::ofstream extlog;71#endif7273#ifdef LOGGING74std::ofstream loga;75#endif7677#ifdef RDP_LOGGING78int log_open = FALSE;79std::ofstream rdp_log;80#endif8182#ifdef RDP_ERROR_LOG83int elog_open = FALSE;84std::ofstream rdp_err;85#endif8687GFX_INFO gfx;8889/* definitions of pointers to Core config functions */90ptr_ConfigOpenSection ConfigOpenSection = NULL;91ptr_ConfigSetParameter ConfigSetParameter = NULL;92ptr_ConfigGetParameter ConfigGetParameter = NULL;93ptr_ConfigGetParameterHelp ConfigGetParameterHelp = NULL;94ptr_ConfigSetDefaultInt ConfigSetDefaultInt = NULL;95ptr_ConfigSetDefaultFloat ConfigSetDefaultFloat = NULL;96ptr_ConfigSetDefaultBool ConfigSetDefaultBool = NULL;97ptr_ConfigSetDefaultString ConfigSetDefaultString = NULL;98ptr_ConfigGetParamInt ConfigGetParamInt = NULL;99ptr_ConfigGetParamFloat ConfigGetParamFloat = NULL;100ptr_ConfigGetParamBool ConfigGetParamBool = NULL;101ptr_ConfigGetParamString ConfigGetParamString = NULL;102103ptr_ConfigGetSharedDataFilepath ConfigGetSharedDataFilepath = NULL;104ptr_ConfigGetUserConfigPath ConfigGetUserConfigPath = NULL;105ptr_ConfigGetUserDataPath ConfigGetUserDataPath = NULL;106ptr_ConfigGetUserCachePath ConfigGetUserCachePath = NULL;107108/* definitions of pointers to Core video extension functions */109ptr_VidExt_Init CoreVideo_Init = NULL;110ptr_VidExt_Quit CoreVideo_Quit = NULL;111ptr_VidExt_ListFullscreenModes CoreVideo_ListFullscreenModes = NULL;112ptr_VidExt_SetVideoMode CoreVideo_SetVideoMode = NULL;113ptr_VidExt_SetCaption CoreVideo_SetCaption = NULL;114ptr_VidExt_ToggleFullScreen CoreVideo_ToggleFullScreen = NULL;115ptr_VidExt_ResizeWindow CoreVideo_ResizeWindow = NULL;116ptr_VidExt_GL_GetProcAddress CoreVideo_GL_GetProcAddress = NULL;117ptr_VidExt_GL_SetAttribute CoreVideo_GL_SetAttribute = NULL;118ptr_VidExt_GL_SwapBuffers CoreVideo_GL_SwapBuffers = NULL;119int to_fullscreen = FALSE;120int fullscreen = FALSE;121int romopen = FALSE;122GrContext_t gfx_context = 0;123int debugging = FALSE;124int exception = FALSE;125126int evoodoo = 0;127int ev_fullscreen = 0;128129enum {130NONE,131ASB,132BANJO2,133BAR,134CHOPPER,135DIDDY,136FIFA98,137FZERO,138GOLDENEYE,139HYPERBIKE,140ISS64,141KI,142KNOCKOUT,143LEGO,144MK64,145MEGAMAN,146MAKERS,147WCWNITRO,148OGRE64,149PILOTWINGS,150PMARIO,151PPL,152RE2,153STARCRAFT,154SUPERCROSS,155TGR,156TGR2,157TONIC,158YOSHI,159ZELDA160};161162#ifdef __WINDOWS__163#define WINPROC_OVERRIDE164#endif165166#ifdef WINPROC_OVERRIDE167LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);168WNDPROC oldWndProc = NULL;169WNDPROC myWndProc = NULL;170#endif171172#ifdef ALTTAB_FIX173HHOOK hhkLowLevelKybd = NULL;174LRESULT CALLBACK LowLevelKeyboardProc(int nCode,175WPARAM wParam, LPARAM lParam);176#endif177178#ifdef PERFORMANCE179int64 perf_cur;180int64 perf_next;181#endif182183#ifdef FPS184LARGE_INTEGER perf_freq;185LARGE_INTEGER fps_last;186LARGE_INTEGER fps_next;187float fps = 0.0f;188wxUint32 fps_count = 0;189190wxUint32 vi_count = 0;191float vi = 0.0f;192193wxUint32 region = 0;194195float ntsc_percent = 0.0f;196float pal_percent = 0.0f;197198#endif199200// ref rate201// 60=0x0, 70=0x1, 72=0x2, 75=0x3, 80=0x4, 90=0x5, 100=0x6, 85=0x7, 120=0x8, none=0xff202203unsigned long BMASK = 0x7FFFFF;204// Reality display processor structure205RDP rdp;206207SETTINGS settings = { FALSE, 640, 480, GR_RESOLUTION_640x480, 0 };208209HOTKEY_INFO hotkey_info;210211VOODOO voodoo = {0, 0, 0, 0,2120, 0, 0, 0,2130, 0, 0, 0214};215216GrTexInfo fontTex;217GrTexInfo cursorTex;218wxUint32 offset_font = 0;219wxUint32 offset_cursor = 0;220wxUint32 offset_textures = 0;221wxUint32 offset_texbuf1 = 0;222223int capture_screen = 0;224char capture_path[256];225226SDL_sem *mutexProcessDList = SDL_CreateSemaphore(1);227228// SOME FUNCTION DEFINITIONS229230static void DrawFrameBuffer ();231232233void (*renderCallback)(int) = NULL;234static void (*l_DebugCallback)(void *, int, const char *) = NULL;235static void *l_DebugCallContext = NULL;236237void _ChangeSize ()238{239rdp.scale_1024 = settings.scr_res_x / 1024.0f;240rdp.scale_768 = settings.scr_res_y / 768.0f;241242// float res_scl_x = (float)settings.res_x / 320.0f;243float res_scl_y = (float)settings.res_y / 240.0f;244245wxUint32 scale_x = *gfx.VI_X_SCALE_REG & 0xFFF;246if (!scale_x) return;247wxUint32 scale_y = *gfx.VI_Y_SCALE_REG & 0xFFF;248if (!scale_y) return;249250float fscale_x = (float)scale_x / 1024.0f;251float fscale_y = (float)scale_y / 2048.0f;252253wxUint32 dwHStartReg = *gfx.VI_H_START_REG;254wxUint32 dwVStartReg = *gfx.VI_V_START_REG;255256wxUint32 hstart = dwHStartReg >> 16;257wxUint32 hend = dwHStartReg & 0xFFFF;258259// dunno... but sometimes this happens260if (hend == hstart) hend = (int)(*gfx.VI_WIDTH_REG / fscale_x);261262wxUint32 vstart = dwVStartReg >> 16;263wxUint32 vend = dwVStartReg & 0xFFFF;264265rdp.vi_width = (hend - hstart) * fscale_x;266rdp.vi_height = (vend - vstart) * fscale_y * 1.0126582f;267float aspect = (settings.adjust_aspect && (fscale_y > fscale_x) && (rdp.vi_width > rdp.vi_height)) ? fscale_x/fscale_y : 1.0f;268269#ifdef LOGGING270sprintf (out_buf, "hstart: %d, hend: %d, vstart: %d, vend: %d\n", hstart, hend, vstart, vend);271LOG (out_buf);272sprintf (out_buf, "size: %d x %d\n", (int)rdp.vi_width, (int)rdp.vi_height);273LOG (out_buf);274#endif275276rdp.scale_x = (float)settings.res_x / rdp.vi_width;277if (region > 0 && settings.pal230)278{279// odd... but pal games seem to want 230 as height...280rdp.scale_y = res_scl_y * (230.0f / rdp.vi_height) * aspect;281}282else283{284rdp.scale_y = (float)settings.res_y / rdp.vi_height * aspect;285}286// rdp.offset_x = settings.offset_x * res_scl_x;287// rdp.offset_y = settings.offset_y * res_scl_y;288//rdp.offset_x = 0;289// rdp.offset_y = 0;290rdp.offset_y = ((float)settings.res_y - rdp.vi_height * rdp.scale_y) * 0.5f;291if (((wxUint32)rdp.vi_width <= (*gfx.VI_WIDTH_REG)/2) && (rdp.vi_width > rdp.vi_height))292rdp.scale_y *= 0.5f;293294rdp.scissor_o.ul_x = 0;295rdp.scissor_o.ul_y = 0;296rdp.scissor_o.lr_x = (wxUint32)rdp.vi_width;297rdp.scissor_o.lr_y = (wxUint32)rdp.vi_height;298299rdp.update |= UPDATE_VIEWPORT | UPDATE_SCISSOR;300}301302void ChangeSize ()303{304if (debugging)305{306_ChangeSize ();307return;308}309switch (settings.aspectmode)310{311case 0: //4:3312if (settings.scr_res_x >= settings.scr_res_y * 4.0f / 3.0f) {313settings.res_y = settings.scr_res_y;314settings.res_x = (wxUint32)(settings.res_y * 4.0f / 3.0f);315} else {316settings.res_x = settings.scr_res_x;317settings.res_y = (wxUint32)(settings.res_x / 4.0f * 3.0f);318}319break;320case 1: //16:9321if (settings.scr_res_x >= settings.scr_res_y * 16.0f / 9.0f) {322settings.res_y = settings.scr_res_y;323settings.res_x = (wxUint32)(settings.res_y * 16.0f / 9.0f);324} else {325settings.res_x = settings.scr_res_x;326settings.res_y = (wxUint32)(settings.res_x / 16.0f * 9.0f);327}328break;329default: //stretch or original330settings.res_x = settings.scr_res_x;331settings.res_y = settings.scr_res_y;332}333_ChangeSize ();334rdp.offset_x = (settings.scr_res_x - settings.res_x) / 2.0f;335float offset_y = (settings.scr_res_y - settings.res_y) / 2.0f;336settings.res_x += (wxUint32)rdp.offset_x;337settings.res_y += (wxUint32)offset_y;338rdp.offset_y += offset_y;339if (settings.aspectmode == 3) // original340{341rdp.scale_x = rdp.scale_y = 1.0f;342rdp.offset_x = (settings.scr_res_x - rdp.vi_width) / 2.0f;343rdp.offset_y = (settings.scr_res_y - rdp.vi_height) / 2.0f;344}345// settings.res_x = settings.scr_res_x;346// settings.res_y = settings.scr_res_y;347}348349void ConfigWrapper()350{351char strConfigWrapperExt[] = "grConfigWrapperExt";352GRCONFIGWRAPPEREXT grConfigWrapperExt = (GRCONFIGWRAPPEREXT)grGetProcAddress(strConfigWrapperExt);353if (grConfigWrapperExt)354grConfigWrapperExt(settings.wrpResolution, settings.wrpVRAM * 1024 * 1024, settings.wrpFBO, settings.wrpAnisotropic);355}356/*357static wxConfigBase * OpenIni()358{359wxConfigBase * ini = wxConfigBase::Get(false);360if (!ini)361{362if (iniName.IsEmpty())363iniName = pluginPath + wxT("/Glide64mk2.ini");364if (wxFileExists(iniName))365{366wxFileInputStream is(iniName);367wxFileConfig * fcfg = new wxFileConfig(is, wxConvISO8859_1);368wxConfigBase::Set(fcfg);369ini = fcfg;370}371}372if (!ini)373wxMessageBox(_T("Can not find ini file! Plugin will not run properly."), _T("File not found"), wxOK|wxICON_EXCLAMATION);374return ini;375}376*/377#ifndef OLDAPI378void WriteLog(m64p_msg_level level, const char *msg, ...)379{380char buf[1024];381va_list args;382va_start(args, msg);383vsnprintf(buf, 1023, msg, args);384buf[1023]='\0';385va_end(args);386if (l_DebugCallback)387{388l_DebugCallback(l_DebugCallContext, level, buf);389}390}391#endif392393void ReadSettings ()394{395// LOG("ReadSettings\n");396if (!Config_Open())397{398ERRLOG("Could not open configuration!");399return;400}401402settings.card_id = (BYTE)Config_ReadInt ("card_id", "Card ID", 0, TRUE, FALSE);403//settings.lang_id not needed404// depth_bias = -Config_ReadInt ("depth_bias", "Depth bias level", 0, TRUE, FALSE);405settings.res_data = 0;406settings.scr_res_x = settings.res_x = Config_ReadScreenInt("ScreenWidth");407settings.scr_res_y = settings.res_y = Config_ReadScreenInt("ScreenHeight");408409settings.vsync = (BOOL)Config_ReadInt ("vsync", "Vertical sync", 0);410settings.ssformat = (BOOL)Config_ReadInt("ssformat", "TODO:ssformat", 0);411//settings.fast_crc = (BOOL)Config_ReadInt ("fast_crc", "Fast CRC", 0);412413settings.show_fps = (BYTE)Config_ReadInt ("show_fps", "Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent", 0, TRUE, FALSE);414settings.clock = (BOOL)Config_ReadInt ("clock", "Clock enabled", 0);415settings.clock_24_hr = (BOOL)Config_ReadInt ("clock_24_hr", "Clock is 24-hour", 0);416// settings.advanced_options only good for GUI config417// settings.texenh_options = only good for GUI config418//settings.use_hotkeys = ini->Read(_T("hotkeys"), 1l);419420settings.wrpResolution = (BYTE)Config_ReadInt ("wrpResolution", "Wrapper resolution", 0, TRUE, FALSE);421settings.wrpVRAM = (BYTE)Config_ReadInt ("wrpVRAM", "Wrapper VRAM", 0, TRUE, FALSE);422settings.wrpFBO = (BOOL)Config_ReadInt ("wrpFBO", "Wrapper FBO", 1, TRUE, TRUE);423settings.wrpAnisotropic = (BOOL)Config_ReadInt ("wrpAnisotropic", "Wrapper Anisotropic Filtering", 0, TRUE, TRUE);424425#ifndef _ENDUSER_RELEASE_426settings.autodetect_ucode = (BOOL)Config_ReadInt ("autodetect_ucode", "Auto-detect microcode", 1);427settings.ucode = (wxUint32)Config_ReadInt ("ucode", "Force microcode", 2, TRUE, FALSE);428settings.wireframe = (BOOL)Config_ReadInt ("wireframe", "Wireframe display", 0);429settings.wfmode = (int)Config_ReadInt ("wfmode", "Wireframe mode: 0=Normal colors, 1=Vertex colors, 2=Red only", 1, TRUE, FALSE);430431settings.logging = (BOOL)Config_ReadInt ("logging", "Logging", 0);432settings.log_clear = (BOOL)Config_ReadInt ("log_clear", "", 0);433434settings.run_in_window = (BOOL)Config_ReadInt ("run_in_window", "", 0);435436settings.elogging = (BOOL)Config_ReadInt ("elogging", "", 0);437settings.filter_cache = (BOOL)Config_ReadInt ("filter_cache", "Filter cache", 0);438settings.unk_as_red = (BOOL)Config_ReadInt ("unk_as_red", "Display unknown combines as red", 0);439settings.log_unk = (BOOL)Config_ReadInt ("log_unk", "Log unknown combines", 0);440settings.unk_clear = (BOOL)Config_ReadInt ("unk_clear", "", 0);441#else442settings.autodetect_ucode = TRUE;443settings.ucode = 2;444settings.wireframe = FALSE;445settings.wfmode = 0;446settings.logging = FALSE;447settings.log_clear = FALSE;448settings.run_in_window = FALSE;449settings.elogging = FALSE;450settings.filter_cache = FALSE;451settings.unk_as_red = FALSE;452settings.log_unk = FALSE;453settings.unk_clear = FALSE;454#endif455456#ifdef TEXTURE_FILTER457458// settings.ghq_fltr range is 0 through 6459// Filters:\nApply a filter to either smooth or sharpen textures.\nThere are 4 different smoothing filters and 2 different sharpening filters.\nThe higher the number, the stronger the effect,\ni.e. \"Smoothing filter 4\" will have a much more noticeable effect than \"Smoothing filter 1\".\nBe aware that performance may have an impact depending on the game and/or the PC.\n[Recommended: your preference]460// _("None"),461// _("Smooth filtering 1"),462// _("Smooth filtering 2"),463// _("Smooth filtering 3"),464// _("Smooth filtering 4"),465// _("Sharp filtering 1"),466// _("Sharp filtering 2")467468// settings.ghq_cmpr 0=S3TC and 1=FXT1469470//settings.ghq_ent is ___471// "Texture enhancement:\n7 different filters are selectable here, each one with a distinctive look.\nBe aware of possible performance impacts.\n\nIMPORTANT: 'Store' mode - saves textures in cache 'as is'. It can improve performance in games, which load many textures.\nDisable 'Ignore backgrounds' option for better result.\n\n[Recommended: your preference]"472473474475settings.ghq_fltr = Config_ReadInt ("ghq_fltr", "Texture Enhancement: Smooth/Sharpen Filters", 0, TRUE, FALSE);476settings.ghq_cmpr = Config_ReadInt ("ghq_cmpr", "Texture Compression: 0 for S3TC, 1 for FXT1", 0, TRUE, FALSE);477settings.ghq_enht = Config_ReadInt ("ghq_enht", "Texture Enhancement: More filters", 0, TRUE, FALSE);478settings.ghq_hirs = Config_ReadInt ("ghq_hirs", "Hi-res texture pack format (0 for none, 1 for Rice)", 0, TRUE, FALSE);479settings.ghq_enht_cmpr = Config_ReadInt ("ghq_enht_cmpr", "Compress texture cache with S3TC or FXT1", 0, TRUE, TRUE);480settings.ghq_enht_tile = Config_ReadInt ("ghq_enht_tile", "Tile textures (saves memory but could cause issues)", 0, TRUE, FALSE);481settings.ghq_enht_f16bpp = Config_ReadInt ("ghq_enht_f16bpp", "Force 16bpp textures (saves ram but lower quality)", 0, TRUE, TRUE);482settings.ghq_enht_gz = Config_ReadInt ("ghq_enht_gz", "Compress texture cache", 1, TRUE, TRUE);483settings.ghq_enht_nobg = Config_ReadInt ("ghq_enht_nobg", "Don't enhance textures for backgrounds", 0, TRUE, TRUE);484settings.ghq_hirs_cmpr = Config_ReadInt ("ghq_hirs_cmpr", "Enable S3TC and FXT1 compression", 0, TRUE, TRUE);485settings.ghq_hirs_tile = Config_ReadInt ("ghq_hirs_tile", "Tile hi-res textures (saves memory but could cause issues)", 0, TRUE, TRUE);486settings.ghq_hirs_f16bpp = Config_ReadInt ("ghq_hirs_f16bpp", "Force 16bpp hi-res textures (saves ram but lower quality)", 0, TRUE, TRUE);487settings.ghq_hirs_gz = Config_ReadInt ("ghq_hirs_gz", "Compress hi-res texture cache", 1, TRUE, TRUE);488settings.ghq_hirs_altcrc = Config_ReadInt ("ghq_hirs_altcrc", "Alternative CRC calculation -- emulates Rice bug", 1, TRUE, TRUE);489settings.ghq_cache_save = Config_ReadInt ("ghq_cache_save", "Save tex cache to disk", 1, TRUE, TRUE);490settings.ghq_cache_size = Config_ReadInt ("ghq_cache_size", "Texture Cache Size (MB)", 128, TRUE, FALSE);491settings.ghq_hirs_let_texartists_fly = Config_ReadInt ("ghq_hirs_let_texartists_fly", "Use full alpha channel -- could cause issues for some tex packs", 0, TRUE, TRUE);492settings.ghq_hirs_dump = Config_ReadInt ("ghq_hirs_dump", "Dump textures", 0, FALSE, TRUE);493#endif494//TODO-PORT: remove?495ConfigWrapper();496}497498void ReadSpecialSettings (const char * name)499{500// char buf [256];501// sprintf(buf, "ReadSpecialSettings. Name: %s\n", name);502// LOG(buf);503504int EnableHacksForGame = (int)Config_ReadInt ("enable_hacks_for_game", "???", 0, TRUE, FALSE);505506switch (EnableHacksForGame)507{508case NONE:509break;510case ASB:511settings.hacks |= hack_ASB;512break;513case BANJO2:514settings.hacks |= hack_Banjo2;515break;516case BAR:517settings.hacks |= hack_BAR;518break;519case CHOPPER:520settings.hacks |= hack_Chopper;521break;522case DIDDY:523settings.hacks |= hack_Diddy;524break;525case FIFA98:526settings.hacks |= hack_Fifa98;527break;528case FZERO:529settings.hacks |= hack_Fzero;530break;531case GOLDENEYE:532settings.hacks |= hack_GoldenEye;533break;534case HYPERBIKE:535settings.hacks |= hack_Hyperbike;536break;537case ISS64:538settings.hacks |= hack_ISS64;539break;540case KI:541settings.hacks |= hack_KI;542break;543case KNOCKOUT:544settings.hacks |= hack_Knockout;545break;546case LEGO:547settings.hacks |= hack_Lego;548break;549case MK64:550settings.hacks |= hack_MK64;551break;552case MEGAMAN:553settings.hacks |= hack_Megaman;554break;555case MAKERS:556settings.hacks |= hack_Makers;557break;558case WCWNITRO:559settings.hacks |= hack_WCWnitro;560break;561case OGRE64:562settings.hacks |= hack_Ogre64;563break;564case PILOTWINGS:565settings.hacks |= hack_Pilotwings;566break;567case PMARIO:568settings.hacks |= hack_PMario;569break;570case PPL:571settings.hacks |= hack_PPL;572break;573case RE2:574settings.hacks |= hack_RE2;575break;576case STARCRAFT:577settings.hacks |= hack_Starcraft;578break;579case SUPERCROSS:580settings.hacks |= hack_Supercross;581break;582case TGR:583settings.hacks |= hack_TGR;584break;585case TGR2:586settings.hacks |= hack_TGR2;587break;588case TONIC:589settings.hacks |= hack_Tonic;590break;591case YOSHI:592settings.hacks |= hack_Yoshi;593break;594case ZELDA:595settings.hacks |= hack_Zelda;596break;597}598599settings.alt_tex_size = (BOOL)Config_ReadInt("alt_tex_size", "???", TRUE);600settings.use_sts1_only = (BOOL)Config_ReadInt("use_sts1_only", "???", FALSE);601settings.force_calc_sphere = (BOOL)Config_ReadInt("force_calc_sphere", "???", FALSE);602settings.correct_viewport = (BOOL)Config_ReadInt("correct_viewport", "???", FALSE);603settings.increase_texrect_edge = (BOOL)Config_ReadInt("increase_texrect_edge", "???", FALSE);604settings.decrease_fillrect_edge = (BOOL)Config_ReadInt("decrease_fillrect_edge", "???", FALSE);605settings.texture_correction = (BOOL)Config_ReadInt("texture_correction", "???", TRUE);606607settings.force_microcheck = (BOOL)Config_ReadInt("force_microcheck", "???", FALSE);608settings.fog = (BOOL)Config_ReadInt("fog", "???", TRUE);609settings.buff_clear = (BOOL)Config_ReadInt("buff_clear", "???", TRUE);610settings.swapmode = (int)Config_ReadInt("swapmode", "???", 1, TRUE, FALSE);611int stipple_pattern = (int)Config_ReadInt("stipple_pattern", "???", 1041204192, TRUE, FALSE);612if (stipple_pattern > 0) settings.stipple_pattern = (wxUint32)stipple_pattern;613settings.stipple_mode = (int)Config_ReadInt("stipple_mode", "???", 2, TRUE, FALSE);614settings.lodmode = (int)Config_ReadInt("lodmode", "???", 0, TRUE, FALSE);615settings.filtering = (int)Config_ReadInt("filtering", "???", 0, TRUE, FALSE);616settings.pal230 = (BOOL)Config_ReadInt("pal230", "???", FALSE);617settings.texture_correction = (BOOL)Config_ReadInt("texture_correction", "???", TRUE);618settings.n64_z_scale = (BOOL)Config_ReadInt("n64_z_scale", "???", FALSE);619settings.old_style_adither = (BOOL)Config_ReadInt("old_style_adither", "???", FALSE);620settings.zmode_compare_less = (BOOL)Config_ReadInt("zmode_compare_less", "???", FALSE);621settings.adjust_aspect = (BOOL)Config_ReadInt("adjust_aspect", "???", TRUE);622settings.clip_zmax = (BOOL)Config_ReadInt("clip_zmax", "???", TRUE);623settings.clip_zmin = (BOOL)Config_ReadInt("clip_zmin", "???", FALSE);624settings.force_quad3d = (BOOL)Config_ReadInt("force_quad3d", "???", FALSE);625settings.aspectmode = (int)Config_ReadInt("aspectmode", "???", 0, TRUE, FALSE);626settings.fast_crc = (BOOL)Config_ReadInt("fast_crc", "???", TRUE);627628if (settings.n64_z_scale)629ZLUT_init();630631//frame buffer632int optimize_texrect = (BOOL)Config_ReadInt("optimize_texrect", "???", TRUE);633int ignore_aux_copy = (BOOL)Config_ReadInt("ignore_aux_copy", "???", FALSE);634int hires_buf_clear = (BOOL)Config_ReadInt("hires_buf_clear", "???", TRUE);635int read_alpha = (BOOL)Config_ReadInt("fb_read_alpha", "???", FALSE);636int useless_is_useless = (BOOL)Config_ReadInt("useless_is_useless", "???", FALSE);637int fb_crc_mode = (int)Config_ReadInt("fb_crc_mode", "???", 1, TRUE, FALSE);638639if (optimize_texrect > 0) settings.frame_buffer |= fb_optimize_texrect;640else if (optimize_texrect == 0) settings.frame_buffer &= ~fb_optimize_texrect;641if (ignore_aux_copy > 0) settings.frame_buffer |= fb_ignore_aux_copy;642else if (ignore_aux_copy == 0) settings.frame_buffer &= ~fb_ignore_aux_copy;643if (hires_buf_clear > 0) settings.frame_buffer |= fb_hwfbe_buf_clear;644else if (hires_buf_clear == 0) settings.frame_buffer &= ~fb_hwfbe_buf_clear;645if (read_alpha > 0) settings.frame_buffer |= fb_read_alpha;646else if (read_alpha == 0) settings.frame_buffer &= ~fb_read_alpha;647if (useless_is_useless > 0) settings.frame_buffer |= fb_useless_is_useless;648else settings.frame_buffer &= ~fb_useless_is_useless;649if (fb_crc_mode >= 0) settings.fb_crc_mode = (SETTINGS::FBCRCMODE)fb_crc_mode;650651//frame buffer652int smart_read = (BOOL)Config_ReadInt("fb_smart", "???", FALSE);653int hires = (BOOL)Config_ReadInt("fb_hires", "???", TRUE);654int read_always = (BOOL)Config_ReadInt("fb_read_always", "???", FALSE);655int read_back_to_screen = (int)Config_ReadInt("read_back_to_screen", "???", 0, TRUE, FALSE);656int cpu_write_hack = (BOOL)Config_ReadInt("detect_cpu_write", "???", FALSE);657int get_fbinfo = (BOOL)Config_ReadInt("fb_get_info", "???", FALSE);658int depth_render = (BOOL)Config_ReadInt("fb_render", "???", TRUE);659660if (smart_read > 0) settings.frame_buffer |= fb_emulation;661else if (smart_read == 0) settings.frame_buffer &= ~fb_emulation;662if (hires > 0) settings.frame_buffer |= fb_hwfbe;663else if (hires == 0) settings.frame_buffer &= ~fb_hwfbe;664if (read_always > 0) settings.frame_buffer |= fb_ref;665else if (read_always == 0) settings.frame_buffer &= ~fb_ref;666if (read_back_to_screen == 1) settings.frame_buffer |= fb_read_back_to_screen;667else if (read_back_to_screen == 2) settings.frame_buffer |= fb_read_back_to_screen2;668else if (read_back_to_screen == 0) settings.frame_buffer &= ~(fb_read_back_to_screen|fb_read_back_to_screen2);669if (cpu_write_hack > 0) settings.frame_buffer |= fb_cpu_write_hack;670else if (cpu_write_hack == 0) settings.frame_buffer &= ~fb_cpu_write_hack;671if (get_fbinfo > 0) settings.frame_buffer |= fb_get_info;672else if (get_fbinfo == 0) settings.frame_buffer &= ~fb_get_info;673if (depth_render > 0) settings.frame_buffer |= fb_depth_render;674else if (depth_render == 0) settings.frame_buffer &= ~fb_depth_render;675settings.frame_buffer |= fb_motionblur;676677settings.flame_corona = (settings.hacks & hack_Zelda) && !fb_depth_render_enabled;678}679680//TODO-PORT: more ini stuff681void WriteSettings (bool saveEmulationSettings)682{683/*684wxConfigBase * ini = OpenIni();685if (!ini || !ini->HasGroup(_T("/SETTINGS")))686return;687ini->SetPath(_T("/SETTINGS"));688689ini->Write(_T("card_id"), settings.card_id);690ini->Write(_T("lang_id"), settings.lang_id);691ini->Write(_T("resolution"), (int)settings.res_data);692ini->Write(_T("ssformat"), settings.ssformat);693ini->Write(_T("vsync"), settings.vsync);694ini->Write(_T("show_fps"), settings.show_fps);695ini->Write(_T("clock"), settings.clock);696ini->Write(_T("clock_24_hr"), settings.clock_24_hr);697ini->Write(_T("advanced_options"), settings.advanced_options);698ini->Write(_T("texenh_options"), settings.texenh_options);699700ini->Write(_T("wrpResolution"), settings.wrpResolution);701ini->Write(_T("wrpVRAM"), settings.wrpVRAM);702ini->Write(_T("wrpFBO"), settings.wrpFBO);703ini->Write(_T("wrpAnisotropic"), settings.wrpAnisotropic);704705#ifndef _ENDUSER_RELEASE_706ini->Write(_T("autodetect_ucode"), settings.autodetect_ucode);707ini->Write(_T("ucode"), (int)settings.ucode);708ini->Write(_T("wireframe"), settings.wireframe);709ini->Write(_T("wfmode"), settings.wfmode);710ini->Write(_T("logging"), settings.logging);711ini->Write(_T("log_clear"), settings.log_clear);712ini->Write(_T("run_in_window"), settings.run_in_window);713ini->Write(_T("elogging"), settings.elogging);714ini->Write(_T("filter_cache"), settings.filter_cache);715ini->Write(_T("unk_as_red"), settings.unk_as_red);716ini->Write(_T("log_unk"), settings.log_unk);717ini->Write(_T("unk_clear"), settings.unk_clear);718#endif //_ENDUSER_RELEASE_719720#ifdef TEXTURE_FILTER721ini->Write(_T("ghq_fltr"), settings.ghq_fltr);722ini->Write(_T("ghq_cmpr"), settings.ghq_cmpr);723ini->Write(_T("ghq_enht"), settings.ghq_enht);724ini->Write(_T("ghq_hirs"), settings.ghq_hirs);725ini->Write(_T("ghq_enht_cmpr"), settings.ghq_enht_cmpr);726ini->Write(_T("ghq_enht_tile"), settings.ghq_enht_tile);727ini->Write(_T("ghq_enht_f16bpp"), settings.ghq_enht_f16bpp);728ini->Write(_T("ghq_enht_gz"), settings.ghq_enht_gz);729ini->Write(_T("ghq_enht_nobg"), settings.ghq_enht_nobg);730ini->Write(_T("ghq_hirs_cmpr"), settings.ghq_hirs_cmpr);731ini->Write(_T("ghq_hirs_tile"), settings.ghq_hirs_tile);732ini->Write(_T("ghq_hirs_f16bpp"), settings.ghq_hirs_f16bpp);733ini->Write(_T("ghq_hirs_gz"), settings.ghq_hirs_gz);734ini->Write(_T("ghq_hirs_altcrc"), settings.ghq_hirs_altcrc);735ini->Write(_T("ghq_cache_save"), settings.ghq_cache_save);736ini->Write(_T("ghq_cache_size"), settings.ghq_cache_size);737ini->Write(_T("ghq_hirs_let_texartists_fly"), settings.ghq_hirs_let_texartists_fly);738ini->Write(_T("ghq_hirs_dump"), settings.ghq_hirs_dump);739#endif740741if (saveEmulationSettings)742{743if (romopen)744{745wxString S = _T("/");746ini->SetPath(S+rdp.RomName);747}748else749ini->SetPath(_T("/DEFAULT"));750ini->Write(_T("filtering"), settings.filtering);751ini->Write(_T("fog"), settings.fog);752ini->Write(_T("buff_clear"), settings.buff_clear);753ini->Write(_T("swapmode"), settings.swapmode);754ini->Write(_T("lodmode"), settings.lodmode);755ini->Write(_T("aspect"), settings.aspectmode);756757ini->Write(_T("fb_read_always"), settings.frame_buffer&fb_ref ? 1 : 0l);758ini->Write(_T("fb_smart"), settings.frame_buffer & fb_emulation ? 1 : 0l);759// ini->Write("motionblur", settings.frame_buffer & fb_motionblur ? 1 : 0);760ini->Write(_T("fb_hires"), settings.frame_buffer & fb_hwfbe ? 1 : 0l);761ini->Write(_T("fb_get_info"), settings.frame_buffer & fb_get_info ? 1 : 0l);762ini->Write(_T("fb_render"), settings.frame_buffer & fb_depth_render ? 1 : 0l);763ini->Write(_T("detect_cpu_write"), settings.frame_buffer & fb_cpu_write_hack ? 1 : 0l);764if (settings.frame_buffer & fb_read_back_to_screen)765ini->Write(_T("read_back_to_screen"), 1);766else if (settings.frame_buffer & fb_read_back_to_screen2)767ini->Write(_T("read_back_to_screen"), 2);768else769ini->Write(_T("read_back_to_screen"), 0l);770}771772wxFileOutputStream os(iniName);773((wxFileConfig*)ini)->Save(os);774*/775}776777GRTEXBUFFEREXT grTextureBufferExt = NULL;778GRTEXBUFFEREXT grTextureAuxBufferExt = NULL;779GRAUXBUFFEREXT grAuxBufferExt = NULL;780GRSTIPPLE grStippleModeExt = NULL;781GRSTIPPLE grStipplePatternExt = NULL;782FxBool (FX_CALL *grKeyPressed)(FxU32) = NULL;783784int GetTexAddrUMA(int tmu, int texsize)785{786int addr = voodoo.tex_min_addr[0] + voodoo.tmem_ptr[0];787voodoo.tmem_ptr[0] += texsize;788voodoo.tmem_ptr[1] = voodoo.tmem_ptr[0];789return addr;790}791int GetTexAddrNonUMA(int tmu, int texsize)792{793int addr = voodoo.tex_min_addr[tmu] + voodoo.tmem_ptr[tmu];794voodoo.tmem_ptr[tmu] += texsize;795return addr;796}797GETTEXADDR GetTexAddr = GetTexAddrNonUMA;798799// guLoadTextures - used to load the cursor and font textures800void guLoadTextures ()801{802if (grTextureBufferExt)803{804int tbuf_size = 0;805if (voodoo.max_tex_size <= 256)806{807grTextureBufferExt( GR_TMU1, voodoo.tex_min_addr[GR_TMU1], GR_LOD_LOG2_256, GR_LOD_LOG2_256,808GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565, GR_MIPMAPLEVELMASK_BOTH );809tbuf_size = 8 * grTexCalcMemRequired(GR_LOD_LOG2_256, GR_LOD_LOG2_256,810GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565);811}812else if (settings.scr_res_x <= 1024)813{814grTextureBufferExt( GR_TMU0, voodoo.tex_min_addr[GR_TMU0], GR_LOD_LOG2_1024, GR_LOD_LOG2_1024,815GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565, GR_MIPMAPLEVELMASK_BOTH );816tbuf_size = grTexCalcMemRequired(GR_LOD_LOG2_1024, GR_LOD_LOG2_1024,817GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565);818grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );819grBufferClear (0, 0, 0xFFFF);820grRenderBuffer( GR_BUFFER_BACKBUFFER );821}822else823{824grTextureBufferExt( GR_TMU0, voodoo.tex_min_addr[GR_TMU0], GR_LOD_LOG2_2048, GR_LOD_LOG2_2048,825GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565, GR_MIPMAPLEVELMASK_BOTH );826tbuf_size = grTexCalcMemRequired(GR_LOD_LOG2_2048, GR_LOD_LOG2_2048,827GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565);828grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );829grBufferClear (0, 0, 0xFFFF);830grRenderBuffer( GR_BUFFER_BACKBUFFER );831}832833rdp.texbufs[0].tmu = GR_TMU0;834rdp.texbufs[0].begin = voodoo.tex_min_addr[GR_TMU0];835rdp.texbufs[0].end = rdp.texbufs[0].begin+tbuf_size;836rdp.texbufs[0].count = 0;837rdp.texbufs[0].clear_allowed = TRUE;838offset_font = tbuf_size;839if (voodoo.num_tmu > 1)840{841rdp.texbufs[1].tmu = GR_TMU1;842rdp.texbufs[1].begin = voodoo.tex_UMA ? rdp.texbufs[0].end : voodoo.tex_min_addr[GR_TMU1];843rdp.texbufs[1].end = rdp.texbufs[1].begin+tbuf_size;844rdp.texbufs[1].count = 0;845rdp.texbufs[1].clear_allowed = TRUE;846if (voodoo.tex_UMA)847offset_font += tbuf_size;848else849offset_texbuf1 = tbuf_size;850}851}852else853offset_font = 0;854855#include "font.h"856wxUint32 *data = (wxUint32*)font;857wxUint32 cur;858859// ** Font texture **860wxUint8 *tex8 = (wxUint8*)malloc(256*64);861862fontTex.smallLodLog2 = fontTex.largeLodLog2 = GR_LOD_LOG2_256;863fontTex.aspectRatioLog2 = GR_ASPECT_LOG2_4x1;864fontTex.format = GR_TEXFMT_ALPHA_8;865fontTex.data = tex8;866867// Decompression: [1-bit inverse alpha --> 8-bit alpha]868wxUint32 i,b;869for (i=0; i<0x200; i++)870{871// cur = ~*(data++), byteswapped872#ifdef __VISUALC__873cur = _byteswap_ulong(~*(data++));874#else875cur = ~*(data++);876cur = ((cur&0xFF)<<24)|(((cur>>8)&0xFF)<<16)|(((cur>>16)&0xFF)<<8)|((cur>>24)&0xFF);877#endif878879for (b=0x80000000; b!=0; b>>=1)880{881if (cur&b) *tex8 = 0xFF;882else *tex8 = 0x00;883tex8 ++;884}885}886887grTexDownloadMipMap (GR_TMU0,888voodoo.tex_min_addr[GR_TMU0] + offset_font,889GR_MIPMAPLEVELMASK_BOTH,890&fontTex);891892offset_cursor = offset_font + grTexTextureMemRequired (GR_MIPMAPLEVELMASK_BOTH, &fontTex);893894free (fontTex.data);895896// ** Cursor texture **897#include "cursor.h"898data = (wxUint32*)cursor;899900wxUint16 *tex16 = (wxUint16*)malloc(32*32*2);901902cursorTex.smallLodLog2 = cursorTex.largeLodLog2 = GR_LOD_LOG2_32;903cursorTex.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;904cursorTex.format = GR_TEXFMT_ARGB_1555;905cursorTex.data = tex16;906907// Conversion: [16-bit 1555 (swapped) --> 16-bit 1555]908for (i=0; i<0x200; i++)909{910cur = *(data++);911*(tex16++) = (wxUint16)(((cur&0x000000FF)<<8)|((cur&0x0000FF00)>>8));912*(tex16++) = (wxUint16)(((cur&0x00FF0000)>>8)|((cur&0xFF000000)>>24));913}914915grTexDownloadMipMap (GR_TMU0,916voodoo.tex_min_addr[GR_TMU0] + offset_cursor,917GR_MIPMAPLEVELMASK_BOTH,918&cursorTex);919920// Round to higher 16921offset_textures = ((offset_cursor + grTexTextureMemRequired (GR_MIPMAPLEVELMASK_BOTH, &cursorTex))922& 0xFFFFFFF0) + 16;923free (cursorTex.data);924}925926#ifdef TEXTURE_FILTER927void DisplayLoadProgress(const wchar_t *format, ...)928{929va_list args;930wchar_t wbuf[INFO_BUF];931char buf[INFO_BUF];932933// process input934va_start(args, format);935vswprintf(wbuf, INFO_BUF, format, args);936va_end(args);937938// XXX: convert to multibyte939wcstombs(buf, wbuf, INFO_BUF);940941if (fullscreen)942{943float x;944set_message_combiner ();945output (382, 380, 1, "LOADING TEXTURES. PLEASE WAIT...");946int len = min (strlen(buf)*8, 1024);947x = (1024-len)/2.0f;948output (x, 360, 1, buf);949grBufferSwap (0);950grColorMask (FXTRUE, FXTRUE);951grBufferClear (0, 0, 0xFFFF);952}953}954#endif955956int InitGfx ()957{958#ifdef TEXTURE_FILTER959wchar_t romname[256];960wchar_t foldername[PATH_MAX + 64];961wchar_t cachename[PATH_MAX + 64];962#endif963if (fullscreen)964ReleaseGfx ();965966OPEN_RDP_LOG (); // doesn't matter if opens again; it will check for it967OPEN_RDP_E_LOG ();968VLOG ("InitGfx ()\n");969970debugging = FALSE;971rdp_reset ();972973// Initialize Glide974grGlideInit ();975976// Select the Glide device977grSstSelect (settings.card_id);978979// Is mirroring allowed?980const char *extensions = grGetString (GR_EXTENSION);981982// Check which SST we are using and initialize stuff983// Hiroshi Morii <[email protected]>984enum {985GR_SSTTYPE_VOODOO = 0,986GR_SSTTYPE_SST96 = 1,987GR_SSTTYPE_AT3D = 2,988GR_SSTTYPE_Voodoo2 = 3,989GR_SSTTYPE_Banshee = 4,990GR_SSTTYPE_Voodoo3 = 5,991GR_SSTTYPE_Voodoo4 = 6,992GR_SSTTYPE_Voodoo5 = 7993};994const char *hardware = grGetString(GR_HARDWARE);995unsigned int SST_type = GR_SSTTYPE_VOODOO;996if (strstr(hardware, "Rush")) {997SST_type = GR_SSTTYPE_SST96;998} else if (strstr(hardware, "Voodoo2")) {999SST_type = GR_SSTTYPE_Voodoo2;1000} else if (strstr(hardware, "Voodoo Banshee")) {1001SST_type = GR_SSTTYPE_Banshee;1002} else if (strstr(hardware, "Voodoo3")) {1003SST_type = GR_SSTTYPE_Voodoo3;1004} else if (strstr(hardware, "Voodoo4")) {1005SST_type = GR_SSTTYPE_Voodoo4;1006} else if (strstr(hardware, "Voodoo5")) {1007SST_type = GR_SSTTYPE_Voodoo5;1008}1009// 2Mb Texture boundary1010voodoo.has_2mb_tex_boundary = (SST_type < GR_SSTTYPE_Banshee) && !evoodoo;1011// use UMA if available1012voodoo.tex_UMA = FALSE;1013//*1014if (strstr(extensions, " TEXUMA ")) {1015// we get better texture cache hits with UMA on1016grEnable(GR_TEXTURE_UMA_EXT);1017voodoo.tex_UMA = TRUE;1018LOG ("Using TEXUMA extension.\n");1019}1020//*/1021//TODO-PORT: fullscreen stuff1022wxUint32 res_data = settings.res_data;1023char strWrapperFullScreenResolutionExt[] = "grWrapperFullScreenResolutionExt";1024if (ev_fullscreen)1025{1026GRWRAPPERFULLSCREENRESOLUTIONEXT grWrapperFullScreenResolutionExt =1027(GRWRAPPERFULLSCREENRESOLUTIONEXT)grGetProcAddress(strWrapperFullScreenResolutionExt);1028if (grWrapperFullScreenResolutionExt) {1029wxUint32 _width, _height = 0;1030settings.res_data = grWrapperFullScreenResolutionExt(&_width, &_height);1031settings.scr_res_x = settings.res_x = _width;1032settings.scr_res_y = settings.res_y = _height;1033}1034res_data = settings.res_data;1035}1036else if (evoodoo)1037{1038GRWRAPPERFULLSCREENRESOLUTIONEXT grWrapperFullScreenResolutionExt =1039(GRWRAPPERFULLSCREENRESOLUTIONEXT)grGetProcAddress(strWrapperFullScreenResolutionExt);1040if (grWrapperFullScreenResolutionExt != NULL)1041{1042/*1043TODO-port: fix resolutions1044settings.res_data = settings.res_data_org;1045settings.scr_res_x = settings.res_x = resolutions[settings.res_data][0];1046settings.scr_res_y = settings.res_y = resolutions[settings.res_data][1];1047*/1048}1049res_data = settings.res_data | 0x80000000;1050}10511052gfx_context = 0;10531054// Select the window10551056if (fb_hwfbe_enabled)1057{1058char strSstWinOpenExt[] ="grSstWinOpenExt";1059GRWINOPENEXT grSstWinOpenExt = (GRWINOPENEXT)grGetProcAddress(strSstWinOpenExt);1060if (grSstWinOpenExt)1061gfx_context = grSstWinOpenExt ((FxU32)NULL,1062res_data,1063GR_REFRESH_60Hz,1064GR_COLORFORMAT_RGBA,1065GR_ORIGIN_UPPER_LEFT,1066fb_emulation_enabled?GR_PIXFMT_RGB_565:GR_PIXFMT_ARGB_8888, //32b color is not compatible with fb emulation10672, // Double-buffering10681); // 1 auxillary buffer1069}1070if (!gfx_context)1071gfx_context = grSstWinOpen ((FxU32)NULL,1072res_data,1073GR_REFRESH_60Hz,1074GR_COLORFORMAT_RGBA,1075GR_ORIGIN_UPPER_LEFT,10762, // Double-buffering10771); // 1 auxillary buffer10781079if (!gfx_context)1080{1081ERRLOG("Error setting display mode");1082// grSstWinClose (gfx_context);1083grGlideShutdown ();1084return FALSE;1085}10861087fullscreen = TRUE;1088to_fullscreen = FALSE;108910901091// get the # of TMUs available1092grGet (GR_NUM_TMU, 4, (FxI32*)&voodoo.num_tmu);1093// get maximal texture size1094grGet (GR_MAX_TEXTURE_SIZE, 4, (FxI32*)&voodoo.max_tex_size);1095voodoo.sup_large_tex = (voodoo.max_tex_size > 256 && !(settings.hacks & hack_PPL));10961097//num_tmu = 1;1098if (voodoo.tex_UMA)1099{1100GetTexAddr = GetTexAddrUMA;1101voodoo.tex_min_addr[0] = voodoo.tex_min_addr[1] = grTexMinAddress(GR_TMU0);1102voodoo.tex_max_addr[0] = voodoo.tex_max_addr[1] = grTexMaxAddress(GR_TMU0);1103}1104else1105{1106GetTexAddr = GetTexAddrNonUMA;1107voodoo.tex_min_addr[0] = grTexMinAddress(GR_TMU0);1108voodoo.tex_min_addr[1] = grTexMinAddress(GR_TMU1);1109voodoo.tex_max_addr[0] = grTexMaxAddress(GR_TMU0);1110voodoo.tex_max_addr[1] = grTexMaxAddress(GR_TMU1);1111}11121113if (strstr (extensions, "TEXMIRROR") && !(settings.hacks&hack_Zelda)) //zelda's trees suffer from hardware mirroring1114voodoo.sup_mirroring = 1;1115else1116voodoo.sup_mirroring = 0;11171118if (strstr (extensions, "TEXFMT")) //VSA100 texture format extension1119voodoo.sup_32bit_tex = TRUE;1120else1121voodoo.sup_32bit_tex = FALSE;11221123voodoo.gamma_correction = 0;1124if (strstr(extensions, "GETGAMMA"))1125grGet(GR_GAMMA_TABLE_ENTRIES, sizeof(voodoo.gamma_table_size), &voodoo.gamma_table_size);11261127if (fb_hwfbe_enabled)1128{1129if (char * extstr = (char*)strstr(extensions, "TEXTUREBUFFER"))1130{1131if (!strncmp(extstr, "TEXTUREBUFFER", 13))1132{1133char strTextureBufferExt[] = "grTextureBufferExt";1134grTextureBufferExt = (GRTEXBUFFEREXT) grGetProcAddress(strTextureBufferExt);1135char strTextureAuxBufferExt[] = "grTextureAuxBufferExt";1136grTextureAuxBufferExt = (GRTEXBUFFEREXT) grGetProcAddress(strTextureAuxBufferExt);1137char strAuxBufferExt[] = "grAuxBufferExt";1138grAuxBufferExt = (GRAUXBUFFEREXT) grGetProcAddress(strAuxBufferExt);1139}1140}1141else1142settings.frame_buffer &= ~fb_hwfbe;1143}1144else1145grTextureBufferExt = 0;11461147grStippleModeExt = (GRSTIPPLE)grStippleMode;1148grStipplePatternExt = (GRSTIPPLE)grStipplePattern;11491150if (grStipplePatternExt)1151grStipplePatternExt(settings.stipple_pattern);11521153// char strKeyPressedExt[] = "grKeyPressedExt";1154// grKeyPressed = (FxBool (FX_CALL *)(FxU32))grGetProcAddress (strKeyPressedExt);11551156InitCombine();11571158#ifdef SIMULATE_VOODOO11159voodoo.num_tmu = 1;1160voodoo.sup_mirroring = 0;1161#endif11621163#ifdef SIMULATE_BANSHEE1164voodoo.num_tmu = 1;1165voodoo.sup_mirroring = 1;1166#endif11671168grCoordinateSpace (GR_WINDOW_COORDS);1169grVertexLayout (GR_PARAM_XY, offsetof(VERTEX,x), GR_PARAM_ENABLE);1170grVertexLayout (GR_PARAM_Q, offsetof(VERTEX,q), GR_PARAM_ENABLE);1171grVertexLayout (GR_PARAM_Z, offsetof(VERTEX,z), GR_PARAM_ENABLE);1172grVertexLayout (GR_PARAM_ST0, offsetof(VERTEX,coord[0]), GR_PARAM_ENABLE);1173grVertexLayout (GR_PARAM_ST1, offsetof(VERTEX,coord[2]), GR_PARAM_ENABLE);1174grVertexLayout (GR_PARAM_PARGB, offsetof(VERTEX,b), GR_PARAM_ENABLE);11751176grCullMode(GR_CULL_NEGATIVE);11771178if (settings.fog) //"FOGCOORD" extension1179{1180if (strstr (extensions, "FOGCOORD"))1181{1182GrFog_t fog_t[64];1183guFogGenerateLinear (fog_t, 0.0f, 255.0f);//(float)rdp.fog_multiplier + (float)rdp.fog_offset);//256.0f);11841185for (int i = 63; i > 0; i--)1186{1187if (fog_t[i] - fog_t[i-1] > 63)1188{1189fog_t[i-1] = fog_t[i] - 63;1190}1191}1192fog_t[0] = 0;1193// for (int f = 0; f < 64; f++)1194// {1195// FRDP("fog[%d]=%d->%f\n", f, fog_t[f], guFogTableIndexToW(f));1196// }1197grFogTable (fog_t);1198grVertexLayout (GR_PARAM_FOG_EXT, offsetof(VERTEX,f), GR_PARAM_ENABLE);1199}1200else //not supported1201settings.fog = FALSE;1202}12031204grDepthBufferMode (GR_DEPTHBUFFER_ZBUFFER);1205grDepthBufferFunction(GR_CMP_LESS);1206grDepthMask(FXTRUE);12071208settings.res_x = settings.scr_res_x;1209settings.res_y = settings.scr_res_y;1210ChangeSize ();12111212guLoadTextures ();1213ClearCache ();12141215grCullMode (GR_CULL_DISABLE);1216grDepthBufferMode (GR_DEPTHBUFFER_ZBUFFER);1217grDepthBufferFunction (GR_CMP_ALWAYS);1218grRenderBuffer(GR_BUFFER_BACKBUFFER);1219grColorMask (FXTRUE, FXTRUE);1220grDepthMask (FXTRUE);1221grBufferClear (0, 0, 0xFFFF);1222grBufferSwap (0);1223grBufferClear (0, 0, 0xFFFF);1224grDepthMask (FXFALSE);1225grTexFilterMode (0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR);1226grTexFilterMode (1, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR);1227grTexClampMode (0, GR_TEXTURECLAMP_CLAMP, GR_TEXTURECLAMP_CLAMP);1228grTexClampMode (1, GR_TEXTURECLAMP_CLAMP, GR_TEXTURECLAMP_CLAMP);1229grClipWindow (0, 0, settings.scr_res_x, settings.scr_res_y);1230rdp.update |= UPDATE_SCISSOR | UPDATE_COMBINE | UPDATE_ZBUF_ENABLED | UPDATE_CULL_MODE;12311232#ifdef TEXTURE_FILTER // Hiroshi Morii <[email protected]>1233if (!settings.ghq_use)1234{1235settings.ghq_use = settings.ghq_fltr || settings.ghq_enht /*|| settings.ghq_cmpr*/ || settings.ghq_hirs;1236if (settings.ghq_use)1237{1238/* Plugin path */1239int options = texfltr[settings.ghq_fltr]|texenht[settings.ghq_enht]|texcmpr[settings.ghq_cmpr]|texhirs[settings.ghq_hirs];1240if (settings.ghq_enht_cmpr)1241options |= COMPRESS_TEX;1242if (settings.ghq_hirs_cmpr)1243options |= COMPRESS_HIRESTEX;1244// if (settings.ghq_enht_tile)1245// options |= TILE_TEX;1246if (settings.ghq_hirs_tile)1247options |= TILE_HIRESTEX;1248if (settings.ghq_enht_f16bpp)1249options |= FORCE16BPP_TEX;1250if (settings.ghq_hirs_f16bpp)1251options |= FORCE16BPP_HIRESTEX;1252if (settings.ghq_enht_gz)1253options |= GZ_TEXCACHE;1254if (settings.ghq_hirs_gz)1255options |= GZ_HIRESTEXCACHE;1256if (settings.ghq_cache_save)1257options |= (DUMP_TEXCACHE|DUMP_HIRESTEXCACHE);1258if (settings.ghq_hirs_let_texartists_fly)1259options |= LET_TEXARTISTS_FLY;1260if (settings.ghq_hirs_dump)1261options |= DUMP_TEX;12621263ghq_dmptex_toggle_key = 0;12641265swprintf(romname, sizeof(romname) / sizeof(*romname), L"%hs", rdp.RomName);1266swprintf(foldername, sizeof(foldername) / sizeof(*foldername), L"%hs", ConfigGetUserDataPath());1267swprintf(cachename, sizeof(cachename) / sizeof(*cachename), L"%hs", ConfigGetUserCachePath());12681269settings.ghq_use = (int)ext_ghq_init(voodoo.max_tex_size, // max texture width supported by hardware1270voodoo.max_tex_size, // max texture height supported by hardware1271voodoo.sup_32bit_tex?32:16, // max texture bpp supported by hardware1272options,1273settings.ghq_cache_size * 1024*1024, // cache texture to system memory1274foldername,1275cachename,1276romname, // name of ROM. must be no longer than 256 characters1277DisplayLoadProgress);1278}1279}1280if (settings.ghq_use && strstr (extensions, "TEXMIRROR"))1281voodoo.sup_mirroring = 1;1282#endif12831284return TRUE;1285}12861287void ReleaseGfx ()1288{1289VLOG("ReleaseGfx ()\n");12901291// Restore gamma settings1292if (voodoo.gamma_correction)1293{1294if (voodoo.gamma_table_r)1295grLoadGammaTable(voodoo.gamma_table_size, voodoo.gamma_table_r, voodoo.gamma_table_g, voodoo.gamma_table_b);1296else1297guGammaCorrectionRGB(1.3f, 1.3f, 1.3f); //1.3f is default 3dfx gamma for everything but desktop1298voodoo.gamma_correction = 0;1299}13001301// Release graphics1302grSstWinClose (gfx_context);13031304// Shutdown glide1305grGlideShutdown();13061307fullscreen = FALSE;1308rdp.window_changed = TRUE;1309}13101311// new API code begins here!13121313#ifdef __cplusplus1314extern "C" {1315#endif13161317EXPORT void* CALL GetScreenTextureID()1318{1319//__asm int 3;1320// GrLfbInfo_t info;1321// info.size = sizeof(GrLfbInfo_t);1322// if (grLfbLock (GR_LFB_READ_ONLY,1323// GR_BUFFER_BACKBUFFER,1324// GR_LFBWRITEMODE_888,1325// GR_ORIGIN_UPPER_LEFT,1326// FXFALSE,1327// &info))13281329return NULL;1330}13311332EXPORT void CALL ReadScreen2(void *dest, int *width, int *height, int front)1333{1334VLOG("CALL ReadScreen2 ()\n");1335*width = settings.res_x;1336*height = settings.res_y;1337if (dest)1338{1339BYTE * line = (BYTE*)dest;1340if (!fullscreen)1341{1342for (wxUint32 y=0; y<settings.res_y; y++)1343{1344for (wxUint32 x=0; x<settings.res_x; x++)1345{1346line[x*3] = 0x20;1347line[x*3+1] = 0x7f;1348line[x*3+2] = 0x40;1349}1350}1351// LOG ("ReadScreen. not in the fullscreen!\n");1352WARNLOG("[Glide64] Cannot save screenshot in windowed mode?\n");13531354return;1355}13561357GrLfbInfo_t info;1358info.size = sizeof(GrLfbInfo_t);1359if (grLfbLock (GR_LFB_READ_ONLY,1360GR_BUFFER_BACKBUFFER,1361GR_LFBWRITEMODE_888,1362GR_ORIGIN_UPPER_LEFT,1363FXFALSE,1364&info))1365{1366// Copy the screen, let's hope this works.1367for (wxUint32 y=0; y<settings.res_y; y++)1368{1369BYTE *ptr = (BYTE*) info.lfbPtr + (info.strideInBytes * y);1370for (wxUint32 x=0; x<settings.res_x; x++)1371{1372line[x*4+2] = ptr[2]; // red1373line[x*4+1] = ptr[1]; // green1374line[x*4] = ptr[0]; // blue1375ptr += 4;1376}1377line += settings.res_x * 4;1378}13791380// Unlock the frontbuffer1381grLfbUnlock (GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER);1382}1383VLOG ("ReadScreen. Success.\n");1384}1385}13861387EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context,1388void (*DebugCallback)(void *, int, const char *))1389{1390VLOG("CALL PluginStartup ()\n");1391l_DebugCallback = DebugCallback;1392l_DebugCallContext = Context;13931394/* attach and call the CoreGetAPIVersions function, check Config and Video Extension API versions for compatibility */1395ptr_CoreGetAPIVersions CoreAPIVersionFunc;1396CoreAPIVersionFunc = (ptr_CoreGetAPIVersions) osal_dynlib_getproc(CoreLibHandle, "CoreGetAPIVersions");1397if (CoreAPIVersionFunc == NULL)1398{1399ERRLOG("Core emulator broken; no CoreAPIVersionFunc() function found.");1400return M64ERR_INCOMPATIBLE;1401}1402int ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion;1403(*CoreAPIVersionFunc)(&ConfigAPIVersion, &DebugAPIVersion, &VidextAPIVersion, NULL);1404if ((ConfigAPIVersion & 0xffff0000) != (CONFIG_API_VERSION & 0xffff0000))1405{1406ERRLOG("Emulator core Config API incompatible with this plugin");1407return M64ERR_INCOMPATIBLE;1408}1409if ((VidextAPIVersion & 0xffff0000) != (VIDEXT_API_VERSION & 0xffff0000))1410{1411ERRLOG("Emulator core Video Extension API incompatible with this plugin");1412return M64ERR_INCOMPATIBLE;1413}14141415ConfigOpenSection = (ptr_ConfigOpenSection) osal_dynlib_getproc(CoreLibHandle, "ConfigOpenSection");1416ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigSetParameter");1417ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParameter");1418ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultInt");1419ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultFloat");1420ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultBool");1421ConfigSetDefaultString = (ptr_ConfigSetDefaultString) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultString");1422ConfigGetParamInt = (ptr_ConfigGetParamInt) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamInt");1423ConfigGetParamFloat = (ptr_ConfigGetParamFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamFloat");1424ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamBool");1425ConfigGetParamString = (ptr_ConfigGetParamString) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamString");14261427ConfigGetSharedDataFilepath = (ptr_ConfigGetSharedDataFilepath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetSharedDataFilepath");1428ConfigGetUserConfigPath = (ptr_ConfigGetUserConfigPath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserConfigPath");1429ConfigGetUserDataPath = (ptr_ConfigGetUserDataPath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserDataPath");1430ConfigGetUserCachePath = (ptr_ConfigGetUserCachePath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserCachePath");14311432if (!ConfigOpenSection || !ConfigSetParameter || !ConfigGetParameter ||1433!ConfigSetDefaultInt || !ConfigSetDefaultFloat || !ConfigSetDefaultBool || !ConfigSetDefaultString ||1434!ConfigGetParamInt || !ConfigGetParamFloat || !ConfigGetParamBool || !ConfigGetParamString ||1435!ConfigGetSharedDataFilepath || !ConfigGetUserConfigPath || !ConfigGetUserDataPath || !ConfigGetUserCachePath)1436{1437ERRLOG("Couldn't connect to Core configuration functions");1438return M64ERR_INCOMPATIBLE;1439}14401441/* Get the core Video Extension function pointers from the library handle */1442CoreVideo_Init = (ptr_VidExt_Init) osal_dynlib_getproc(CoreLibHandle, "VidExt_Init");1443CoreVideo_Quit = (ptr_VidExt_Quit) osal_dynlib_getproc(CoreLibHandle, "VidExt_Quit");1444CoreVideo_ListFullscreenModes = (ptr_VidExt_ListFullscreenModes) osal_dynlib_getproc(CoreLibHandle, "VidExt_ListFullscreenModes");1445CoreVideo_SetVideoMode = (ptr_VidExt_SetVideoMode) osal_dynlib_getproc(CoreLibHandle, "VidExt_SetVideoMode");1446CoreVideo_SetCaption = (ptr_VidExt_SetCaption) osal_dynlib_getproc(CoreLibHandle, "VidExt_SetCaption");1447CoreVideo_ToggleFullScreen = (ptr_VidExt_ToggleFullScreen) osal_dynlib_getproc(CoreLibHandle, "VidExt_ToggleFullScreen");1448CoreVideo_ResizeWindow = (ptr_VidExt_ResizeWindow) osal_dynlib_getproc(CoreLibHandle, "VidExt_ResizeWindow");1449CoreVideo_GL_GetProcAddress = (ptr_VidExt_GL_GetProcAddress) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_GetProcAddress");1450CoreVideo_GL_SetAttribute = (ptr_VidExt_GL_SetAttribute) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_SetAttribute");1451CoreVideo_GL_SwapBuffers = (ptr_VidExt_GL_SwapBuffers) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_SwapBuffers");14521453if (!CoreVideo_Init || !CoreVideo_Quit || !CoreVideo_ListFullscreenModes || !CoreVideo_SetVideoMode ||1454!CoreVideo_SetCaption || !CoreVideo_ToggleFullScreen || !CoreVideo_ResizeWindow || !CoreVideo_GL_GetProcAddress ||1455!CoreVideo_GL_SetAttribute || !CoreVideo_GL_SwapBuffers)1456{1457ERRLOG("Couldn't connect to Core video functions");1458return M64ERR_INCOMPATIBLE;1459}14601461CoreVideo_Init();1462ReadSettings();1463return M64ERR_SUCCESS;1464}14651466EXPORT m64p_error CALL PluginShutdown(void)1467{1468VLOG("CALL PluginShutdown ()\n");1469return M64ERR_SUCCESS;1470}14711472EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities)1473{1474VLOG("CALL PluginGetVersion ()\n");1475/* set version info */1476if (PluginType != NULL)1477*PluginType = M64PLUGIN_GFX;14781479if (PluginVersion != NULL)1480*PluginVersion = PLUGIN_VERSION;14811482if (APIVersion != NULL)1483*APIVersion = VIDEO_PLUGIN_API_VERSION;14841485if (PluginNamePtr != NULL)1486*PluginNamePtr = PLUGIN_NAME;14871488if (Capabilities != NULL)1489{1490*Capabilities = 0;1491}14921493return M64ERR_SUCCESS;1494}14951496/******************************************************************1497Function: CaptureScreen1498Purpose: This function dumps the current frame to a file1499input: pointer to the directory to save the file to1500output: none1501*******************************************************************/1502EXPORT void CALL CaptureScreen ( char * Directory )1503{1504capture_screen = 1;1505strcpy (capture_path, Directory);1506}15071508/******************************************************************1509Function: ChangeWindow1510Purpose: to change the window between fullscreen and window1511mode. If the window was in fullscreen this should1512change the screen to window mode and vice vesa.1513input: none1514output: none1515*******************************************************************/1516//#warning ChangeWindow unimplemented1517EXPORT void CALL ChangeWindow (void)1518{1519VLOG ("ChangeWindow()\n");1520#ifdef OLDAPI1521if (evoodoo)1522{1523if (!ev_fullscreen)1524{1525to_fullscreen = TRUE;1526ev_fullscreen = TRUE;1527#ifdef __WINDOWS__1528if (gfx.hStatusBar)1529ShowWindow( gfx.hStatusBar, SW_HIDE );1530ShowCursor( FALSE );1531#endif1532}1533else1534{1535ev_fullscreen = FALSE;1536InitGfx ();1537#ifdef __WINDOWS__1538ShowCursor( TRUE );1539if (gfx.hStatusBar)1540ShowWindow( gfx.hStatusBar, SW_SHOW );1541SetWindowLong (gfx.hWnd, GWL_WNDPROC, (long)oldWndProc);1542#endif1543}1544}1545else1546{1547// Go to fullscreen at next dlist1548// This is for compatibility with 1964, which reloads the plugin1549// when switching to fullscreen1550if (!fullscreen)1551{1552to_fullscreen = TRUE;1553#ifdef __WINDOWS__1554if (gfx.hStatusBar)1555ShowWindow( gfx.hStatusBar, SW_HIDE );1556ShowCursor( FALSE );1557#endif1558}1559else1560{1561ReleaseGfx ();1562#ifdef __WINDOWS__1563ShowCursor( TRUE );1564if (gfx.hStatusBar)1565ShowWindow( gfx.hStatusBar, SW_SHOW );1566// SetWindowLong fixes the following Windows XP Banshee issues:1567// 1964 crash error when loading another rom.1568// All N64 emu's minimize, restore crashes.1569SetWindowLong (gfx.hWnd, GWL_WNDPROC, (long)oldWndProc);1570#endif1571}1572}1573#endif1574}15751576/******************************************************************1577Function: CloseDLL1578Purpose: This function is called when the emulator is closing1579down allowing the dll to de-initialise.1580input: none1581output: none1582*******************************************************************/1583void CALL CloseDLL (void)1584{1585VLOG ("CloseDLL ()\n");15861587// re-set the old window proc1588#ifdef WINPROC_OVERRIDE1589SetWindowLong (gfx.hWnd, GWL_WNDPROC, (long)oldWndProc);1590#endif15911592#ifdef ALTTAB_FIX1593if (hhkLowLevelKybd)1594{1595UnhookWindowsHookEx(hhkLowLevelKybd);1596hhkLowLevelKybd = 0;1597}1598#endif15991600//CLOSELOG ();16011602#ifdef TEXTURE_FILTER // Hiroshi Morii <[email protected]>1603if (settings.ghq_use)1604{1605ext_ghq_shutdown();1606settings.ghq_use = 0;1607}1608#endif1609if (fullscreen)1610ReleaseGfx ();1611ZLUT_release();1612ClearCache ();1613delete[] voodoo.gamma_table_r;1614voodoo.gamma_table_r = 0;1615delete[] voodoo.gamma_table_g;1616voodoo.gamma_table_g = 0;1617delete[] voodoo.gamma_table_b;1618voodoo.gamma_table_b = 0;1619}16201621/******************************************************************1622Function: DllTest1623Purpose: This function is optional function that is provided1624to allow the user to test the dll1625input: a handle to the window that calls this function1626output: none1627*******************************************************************/1628void CALL DllTest ( HWND hParent )1629{1630}16311632/******************************************************************1633Function: DrawScreen1634Purpose: This function is called when the emulator receives a1635WM_PAINT message. This allows the gfx to fit in when1636it is being used in the desktop.1637input: none1638output: none1639*******************************************************************/1640void CALL DrawScreen (void)1641{1642VLOG ("DrawScreen ()\n");1643}16441645/******************************************************************1646Function: GetDllInfo1647Purpose: This function allows the emulator to gather information1648about the dll by filling in the PluginInfo structure.1649input: a pointer to a PLUGIN_INFO stucture that needs to be1650filled by the function. (see def above)1651output: none1652*******************************************************************/1653void CALL GetDllInfo ( PLUGIN_INFO * PluginInfo )1654{1655VLOG ("GetDllInfo ()\n");1656PluginInfo->Version = 0x0103; // Set to 0x01031657PluginInfo->Type = PLUGIN_TYPE_GFX; // Set to PLUGIN_TYPE_GFX1658sprintf (PluginInfo->Name, "Glide64mk2 " G64_VERSION RELTIME); // Name of the DLL16591660// If DLL supports memory these memory options then set them to TRUE or FALSE1661// if it does not support it1662PluginInfo->NormalMemory = TRUE; // a normal wxUint8 array1663PluginInfo->MemoryBswaped = TRUE; // a normal wxUint8 array where the memory has been pre1664// bswap on a dword (32 bits) boundry1665}16661667#ifndef WIN321668BOOL WINAPI QueryPerformanceCounter(PLARGE_INTEGER counter)1669{1670struct timeval tv;16711672/* generic routine */1673gettimeofday( &tv, NULL );1674counter->QuadPart = (LONGLONG)tv.tv_usec + (LONGLONG)tv.tv_sec * 1000000;1675return TRUE;1676}16771678BOOL WINAPI QueryPerformanceFrequency(PLARGE_INTEGER frequency)1679{1680frequency->s.LowPart= 1000000;1681frequency->s.HighPart= 0;1682return TRUE;1683}1684#endif16851686/******************************************************************1687Function: InitiateGFX1688Purpose: This function is called when the DLL is started to give1689information from the emulator that the n64 graphics1690uses. This is not called from the emulation thread.1691Input: Gfx_Info is passed to this function which is defined1692above.1693Output: TRUE on success1694FALSE on failure to initialise16951696** note on interrupts **:1697To generate an interrupt set the appropriate bit in MI_INTR_REG1698and then call the function CheckInterrupts to tell the emulator1699that there is a waiting interrupt.1700*******************************************************************/17011702EXPORT int CALL InitiateGFX (GFX_INFO Gfx_Info)1703{1704VLOG ("InitiateGFX (*)\n");1705voodoo.num_tmu = 2;17061707// Assume scale of 1 for debug purposes1708rdp.scale_x = 1.0f;1709rdp.scale_y = 1.0f;17101711memset (&settings, 0, sizeof(SETTINGS));1712ReadSettings ();1713char name[21] = "DEFAULT";1714ReadSpecialSettings (name);1715settings.res_data_org = settings.res_data;1716#ifdef FPS1717QueryPerformanceFrequency (&perf_freq);1718QueryPerformanceCounter (&fps_last);1719#endif17201721debug_init (); // Initialize debugger17221723gfx = Gfx_Info;17241725#ifdef WINPROC_OVERRIDE1726// [H.Morii] inject our own winproc so that "alt-enter to fullscreen"1727// message is shown when the emulator window is activated.1728WNDPROC curWndProc = (WNDPROC)GetWindowLong(gfx.hWnd, GWL_WNDPROC);1729if (curWndProc && curWndProc != (WNDPROC)WndProc) {1730oldWndProc = (WNDPROC)SetWindowLong (gfx.hWnd, GWL_WNDPROC, (long)WndProc);1731}1732#endif17331734util_init ();1735math_init ();1736TexCacheInit ();1737CRC_BuildTable();1738CountCombine();1739if (fb_depth_render_enabled)1740ZLUT_init();17411742char strConfigWrapperExt[] = "grConfigWrapperExt";1743GRCONFIGWRAPPEREXT grConfigWrapperExt = (GRCONFIGWRAPPEREXT)grGetProcAddress(strConfigWrapperExt);1744if (grConfigWrapperExt)1745grConfigWrapperExt(settings.wrpResolution, settings.wrpVRAM * 1024 * 1024, settings.wrpFBO, settings.wrpAnisotropic);17461747grGlideInit ();1748grSstSelect (0);1749const char *extensions = grGetString (GR_EXTENSION);1750grGlideShutdown ();1751if (strstr (extensions, "EVOODOO"))1752{1753evoodoo = 1;1754voodoo.has_2mb_tex_boundary = 0;1755}1756else {1757evoodoo = 0;1758voodoo.has_2mb_tex_boundary = 1;1759}17601761return TRUE;1762}17631764/******************************************************************1765Function: MoveScreen1766Purpose: This function is called in response to the emulator1767receiving a WM_MOVE passing the xpos and ypos passed1768from that message.1769input: xpos - the x-coordinate of the upper-left corner of the1770client area of the window.1771ypos - y-coordinate of the upper-left corner of the1772client area of the window.1773output: none1774*******************************************************************/1775EXPORT void CALL MoveScreen (int xpos, int ypos)1776{1777rdp.window_changed = TRUE;1778}17791780/******************************************************************1781Function: ResizeVideoOutput1782Purpose: This function is called to force us to resize our output OpenGL window.1783This is currently unsupported, and should never be called because we do1784not pass the RESIZABLE flag to VidExt_SetVideoMode when initializing.1785input: new width and height1786output: none1787*******************************************************************/1788EXPORT void CALL ResizeVideoOutput(int Width, int Height)1789{1790}17911792/******************************************************************1793Function: RomClosed1794Purpose: This function is called when a rom is closed.1795input: none1796output: none1797*******************************************************************/1798EXPORT void CALL RomClosed (void)1799{1800VLOG ("RomClosed ()\n");18011802CLOSE_RDP_LOG ();1803CLOSE_RDP_E_LOG ();1804rdp.window_changed = TRUE;1805romopen = FALSE;1806if (fullscreen && evoodoo)1807ReleaseGfx ();1808}18091810static void CheckDRAMSize()1811{1812wxUint32 test;1813GLIDE64_TRY1814{1815test = gfx.RDRAM[0x007FFFFF] + 1;1816}1817GLIDE64_CATCH1818{1819test = 0;1820}1821if (test)1822BMASK = 0x7FFFFF;1823else1824BMASK = WMASK;1825#ifdef LOGGING1826sprintf (out_buf, "Detected RDRAM size: %08lx\n", BMASK);1827LOG (out_buf);1828#endif1829}18301831/******************************************************************1832Function: RomOpen1833Purpose: This function is called when a rom is open. (from the1834emulation thread)1835input: none1836output: none1837*******************************************************************/1838EXPORT int CALL RomOpen (void)1839{1840VLOG ("RomOpen ()\n");1841no_dlist = true;1842romopen = TRUE;1843ucode_error_report = TRUE; // allowed to report ucode errors1844rdp_reset ();18451846// Get the country code & translate to NTSC(0) or PAL(1)1847wxUint16 code = ((wxUint16*)gfx.HEADER)[0x1F^1];18481849if (code == 0x4400) region = 1; // Germany (PAL)1850if (code == 0x4500) region = 0; // USA (NTSC)1851if (code == 0x4A00) region = 0; // Japan (NTSC)1852if (code == 0x5000) region = 1; // Europe (PAL)1853if (code == 0x5500) region = 0; // Australia (NTSC)18541855char name[21] = "DEFAULT";1856ReadSpecialSettings (name);18571858// get the name of the ROM1859for (int i=0; i<20; i++)1860name[i] = gfx.HEADER[(32+i)^3];1861name[20] = 0;18621863// remove all trailing spaces1864while (name[strlen(name)-1] == ' ')1865name[strlen(name)-1] = 0;18661867strncpy(rdp.RomName, name, sizeof(name));1868ReadSpecialSettings (name);1869ClearCache ();18701871CheckDRAMSize();18721873OPEN_RDP_LOG ();1874OPEN_RDP_E_LOG ();187518761877// ** EVOODOO EXTENSIONS **1878if (!fullscreen)1879{1880grGlideInit ();1881grSstSelect (0);1882}1883const char *extensions = grGetString (GR_EXTENSION);1884if (!fullscreen)1885{1886grGlideShutdown ();18871888if (strstr (extensions, "EVOODOO"))1889evoodoo = 1;1890else1891evoodoo = 0;18921893if (evoodoo)1894InitGfx ();1895}18961897if (strstr (extensions, "ROMNAME"))1898{1899char strSetRomName[] = "grSetRomName";1900void (FX_CALL *grSetRomName)(char*);1901grSetRomName = (void (FX_CALL *)(char*))grGetProcAddress (strSetRomName);1902grSetRomName (name);1903}1904// **1905return true;1906}19071908/******************************************************************1909Function: ShowCFB1910Purpose: Useally once Dlists are started being displayed, cfb is1911ignored. This function tells the dll to start displaying1912them again.1913input: none1914output: none1915*******************************************************************/1916bool no_dlist = true;1917EXPORT void CALL ShowCFB (void)1918{1919no_dlist = true;1920VLOG ("ShowCFB ()\n");1921}19221923EXPORT void CALL SetRenderingCallback(void (*callback)(int))1924{1925VLOG("CALL SetRenderingCallback (*)\n");1926renderCallback = callback;1927}19281929void drawViRegBG()1930{1931LRDP("drawViRegBG\n");1932const wxUint32 VIwidth = *gfx.VI_WIDTH_REG;1933FB_TO_SCREEN_INFO fb_info;1934fb_info.width = VIwidth;1935fb_info.height = (wxUint32)rdp.vi_height;1936if (fb_info.height == 0)1937{1938LRDP("Image height = 0 - skipping\n");1939return;1940}1941fb_info.ul_x = 0;19421943fb_info.lr_x = VIwidth - 1;1944// fb_info.lr_x = (wxUint32)rdp.vi_width - 1;1945fb_info.ul_y = 0;1946fb_info.lr_y = fb_info.height - 1;1947fb_info.opaque = 1;1948fb_info.addr = *gfx.VI_ORIGIN_REG;1949fb_info.size = *gfx.VI_STATUS_REG & 3;1950rdp.last_bg = fb_info.addr;19511952bool drawn = DrawFrameBufferToScreen(fb_info);1953if (settings.hacks&hack_Lego && drawn)1954{1955rdp.updatescreen = 1;1956newSwapBuffers ();1957DrawFrameBufferToScreen(fb_info);1958}1959}19601961}19621963void drawNoFullscreenMessage();19641965void DrawFrameBuffer ()1966{1967if (!fullscreen)1968{1969drawNoFullscreenMessage();1970}1971if (to_fullscreen)1972GoToFullScreen();19731974if (fullscreen)1975{1976grDepthMask (FXTRUE);1977grColorMask (FXTRUE, FXTRUE);1978grBufferClear (0, 0, 0xFFFF);1979drawViRegBG();1980}1981}19821983extern "C" {1984/******************************************************************1985Function: UpdateScreen1986Purpose: This function is called in response to a vsync of the1987screen were the VI bit in MI_INTR_REG has already been1988set1989input: none1990output: none1991*******************************************************************/1992wxUint32 update_screen_count = 0;1993EXPORT void CALL UpdateScreen (void)1994{1995#ifdef LOG_KEY1996if (CheckKeyPressed(G64_VK_SPACE, 0x0001))1997{1998LOG ("KEY!!!\n");1999}2000#endif2001char out_buf[128];2002sprintf (out_buf, "UpdateScreen (). Origin: %08x, Old origin: %08x, width: %d\n", *gfx.VI_ORIGIN_REG, rdp.vi_org_reg, *gfx.VI_WIDTH_REG);2003VLOG (out_buf);2004LRDP(out_buf);20052006wxUint32 width = (*gfx.VI_WIDTH_REG) << 1;2007if (fullscreen && (*gfx.VI_ORIGIN_REG > width))2008update_screen_count++;2009//TODO-PORT: wx times2010#ifdef FPS2011// vertical interrupt has occurred, increment counter2012vi_count ++;20132014// Check frames per second2015LARGE_INTEGER difference;2016QueryPerformanceCounter (&fps_next);2017difference.QuadPart = fps_next.QuadPart - fps_last.QuadPart;2018float diff_secs = (float)((double)difference.QuadPart / (double)perf_freq.QuadPart);2019if (diff_secs > 0.5f)2020{2021fps = (float)(fps_count / diff_secs);2022vi = (float)(vi_count / diff_secs);2023ntsc_percent = vi / 0.6f;2024pal_percent = vi / 0.5f;2025fps_last = fps_next;2026fps_count = 0;2027vi_count = 0;2028}2029#endif2030//*2031wxUint32 limit = (settings.hacks&hack_Lego) ? 15 : 30;2032if ((settings.frame_buffer&fb_cpu_write_hack) && (update_screen_count > limit) && (rdp.last_bg == 0))2033{2034LRDP("DirectCPUWrite hack!\n");2035update_screen_count = 0;2036no_dlist = true;2037ClearCache ();2038UpdateScreen();2039return;2040}2041//*/2042//*2043if( no_dlist )2044{2045if( *gfx.VI_ORIGIN_REG > width )2046{2047ChangeSize ();2048LRDP("ChangeSize done\n");2049DrawFrameBuffer();2050LRDP("DrawFrameBuffer done\n");2051rdp.updatescreen = 1;2052newSwapBuffers ();2053}2054return;2055}2056//*/2057if (settings.swapmode == 0)2058newSwapBuffers ();2059}20602061static void DrawWholeFrameBufferToScreen()2062{2063static wxUint32 toScreenCI = 0;2064if (rdp.ci_width < 200)2065return;2066if (rdp.cimg == toScreenCI)2067return;2068toScreenCI = rdp.cimg;2069FB_TO_SCREEN_INFO fb_info;2070fb_info.addr = rdp.cimg;2071fb_info.size = rdp.ci_size;2072fb_info.width = rdp.ci_width;2073fb_info.height = rdp.ci_height;2074if (fb_info.height == 0)2075return;2076fb_info.ul_x = 0;2077fb_info.lr_x = rdp.ci_width-1;2078fb_info.ul_y = 0;2079fb_info.lr_y = rdp.ci_height-1;2080fb_info.opaque = 0;2081DrawFrameBufferToScreen(fb_info);2082if (!(settings.frame_buffer & fb_ref))2083memset(gfx.RDRAM+rdp.cimg, 0, (rdp.ci_width*rdp.ci_height)<<rdp.ci_size>>1);2084}20852086static void GetGammaTable()2087{2088char strGetGammaTableExt[] = "grGetGammaTableExt";2089void (FX_CALL *grGetGammaTableExt)(FxU32, FxU32*, FxU32*, FxU32*) =2090(void (FX_CALL *)(FxU32, FxU32*, FxU32*, FxU32*))grGetProcAddress(strGetGammaTableExt);2091if (grGetGammaTableExt)2092{2093voodoo.gamma_table_r = new FxU32[voodoo.gamma_table_size];2094voodoo.gamma_table_g = new FxU32[voodoo.gamma_table_size];2095voodoo.gamma_table_b = new FxU32[voodoo.gamma_table_size];2096grGetGammaTableExt(voodoo.gamma_table_size, voodoo.gamma_table_r, voodoo.gamma_table_g, voodoo.gamma_table_b);2097}2098}20992100}2101wxUint32 curframe = 0;2102void newSwapBuffers()2103{2104if (!rdp.updatescreen)2105return;21062107rdp.updatescreen = 0;21082109LRDP("swapped\n");21102111// Allow access to the whole screen2112if (fullscreen)2113{2114rdp.update |= UPDATE_SCISSOR | UPDATE_COMBINE | UPDATE_ZBUF_ENABLED | UPDATE_CULL_MODE;2115grClipWindow (0, 0, settings.scr_res_x, settings.scr_res_y);2116grDepthBufferFunction (GR_CMP_ALWAYS);2117grDepthMask (FXFALSE);2118grCullMode (GR_CULL_DISABLE);21192120if ((settings.show_fps & 0xF) || settings.clock)2121set_message_combiner ();2122#ifdef FPS2123float y = (float)settings.res_y;2124if (settings.show_fps & 0x0F)2125{2126if (settings.show_fps & 4)2127{2128if (region) // PAL2129output (0, y, 0, "%d%% ", (int)pal_percent);2130else2131output (0, y, 0, "%d%% ", (int)ntsc_percent);2132y -= 16;2133}2134if (settings.show_fps & 2)2135{2136output (0, y, 0, "VI/s: %.02f ", vi);2137y -= 16;2138}2139if (settings.show_fps & 1)2140output (0, y, 0, "FPS: %.02f ", fps);2141}2142#endif21432144if (settings.clock)2145{2146if (settings.clock_24_hr)2147{2148time_t ltime;2149time (<ime);2150tm *cur_time = localtime (<ime);21512152sprintf (out_buf, "%.2d:%.2d:%.2d", cur_time->tm_hour, cur_time->tm_min, cur_time->tm_sec);2153}2154else2155{2156char ampm[] = "AM";2157time_t ltime;21582159time (<ime);2160tm *cur_time = localtime (<ime);21612162if (cur_time->tm_hour >= 12)2163{2164strcpy (ampm, "PM");2165if (cur_time->tm_hour != 12)2166cur_time->tm_hour -= 12;2167}2168if (cur_time->tm_hour == 0)2169cur_time->tm_hour = 12;21702171if (cur_time->tm_hour >= 10)2172sprintf (out_buf, "%.5s %s", asctime(cur_time) + 11, ampm);2173else2174sprintf (out_buf, " %.4s %s", asctime(cur_time) + 12, ampm);2175}2176output ((float)(settings.res_x - 68), y, 0, out_buf, 0);2177}2178//hotkeys2179if (CheckKeyPressed(G64_VK_BACK, 0x0001))2180{2181hotkey_info.hk_filtering = 100;2182if (settings.filtering < 2)2183settings.filtering++;2184else2185settings.filtering = 0;2186}2187if ((abs((int)(frame_count - curframe)) > 3 ) && CheckKeyPressed(G64_VK_ALT, 0x8000)) //alt +2188{2189if (CheckKeyPressed(G64_VK_B, 0x8000)) //b2190{2191hotkey_info.hk_motionblur = 100;2192hotkey_info.hk_ref = 0;2193curframe = frame_count;2194settings.frame_buffer ^= fb_motionblur;2195}2196else if (CheckKeyPressed(G64_VK_V, 0x8000)) //v2197{2198hotkey_info.hk_ref = 100;2199hotkey_info.hk_motionblur = 0;2200curframe = frame_count;2201settings.frame_buffer ^= fb_ref;2202}2203}2204if (settings.buff_clear && (hotkey_info.hk_ref || hotkey_info.hk_motionblur || hotkey_info.hk_filtering))2205{2206set_message_combiner ();2207char buf[256];2208buf[0] = 0;2209char * message = 0;2210if (hotkey_info.hk_ref)2211{2212if (settings.frame_buffer & fb_ref)2213message = strcat(buf, "FB READ ALWAYS: ON");2214else2215message = strcat(buf, "FB READ ALWAYS: OFF");2216hotkey_info.hk_ref--;2217}2218if (hotkey_info.hk_motionblur)2219{2220if (settings.frame_buffer & fb_motionblur)2221message = strcat(buf, " MOTION BLUR: ON");2222else2223message = strcat(buf, " MOTION BLUR: OFF");2224hotkey_info.hk_motionblur--;2225}2226if (hotkey_info.hk_filtering)2227{2228switch (settings.filtering)2229{2230case 0:2231message = strcat(buf, " FILTERING MODE: AUTOMATIC");2232break;2233case 1:2234message = strcat(buf, " FILTERING MODE: FORCE BILINEAR");2235break;2236case 2:2237message = strcat(buf, " FILTERING MODE: FORCE POINT-SAMPLED");2238break;2239}2240hotkey_info.hk_filtering--;2241}2242output (120.0f, (float)settings.res_y, 0, message, 0);2243}2244}2245#ifdef OLDAPI2246if (capture_screen)2247{2248//char path[256];2249// Make the directory if it doesn't exist2250if (!wxDirExists(capture_path))2251wxMkdir(capture_path);2252wxString path;2253wxString romName = rdp.RomName;2254romName.Replace(wxT(" "), wxT("_"), true);2255romName.Replace(wxT(":"), wxT(";"), true);22562257for (int i=1; ; i++)2258{2259path = capture_path;2260path += wxT("Glide64mk2_");2261path += romName;2262path += wxT("_");2263if (i < 10)2264path += wxT("0");2265path << i << wxT(".") << ScreenShotFormats[settings.ssformat].extension;2266if (!wxFileName::FileExists(path))2267break;2268}22692270const wxUint32 offset_x = (wxUint32)rdp.offset_x;2271const wxUint32 offset_y = (wxUint32)rdp.offset_y;2272const wxUint32 image_width = settings.scr_res_x - offset_x*2;2273const wxUint32 image_height = settings.scr_res_y - offset_y*2;22742275GrLfbInfo_t info;2276info.size = sizeof(GrLfbInfo_t);2277if (grLfbLock (GR_LFB_READ_ONLY,2278GR_BUFFER_BACKBUFFER,2279GR_LFBWRITEMODE_565,2280GR_ORIGIN_UPPER_LEFT,2281FXFALSE,2282&info))2283{2284wxUint8 *ssimg = (wxUint8*)malloc(image_width * image_height * 3); // will be free in wxImage destructor2285int sspos = 0;2286wxUint32 offset_src = info.strideInBytes * offset_y;22872288// Copy the screen2289if (info.writeMode == GR_LFBWRITEMODE_8888)2290{2291wxUint32 col;2292for (wxUint32 y = 0; y < image_height; y++)2293{2294wxUint32 *ptr = (wxUint32*)((wxUint8*)info.lfbPtr + offset_src);2295ptr += offset_x;2296for (wxUint32 x = 0; x < image_width; x++)2297{2298col = *(ptr++);2299ssimg[sspos++] = (wxUint8)((col >> 16) & 0xFF);2300ssimg[sspos++] = (wxUint8)((col >> 8) & 0xFF);2301ssimg[sspos++] = (wxUint8)(col & 0xFF);2302}2303offset_src += info.strideInBytes;2304}2305}2306else2307{2308wxUint16 col;2309for (wxUint32 y = 0; y < image_height; y++)2310{2311wxUint16 *ptr = (wxUint16*)((wxUint8*)info.lfbPtr + offset_src);2312ptr += offset_x;2313for (wxUint32 x = 0; x < image_width; x++)2314{2315col = *(ptr++);2316ssimg[sspos++] = (wxUint8)((float)(col >> 11) / 31.0f * 255.0f);2317ssimg[sspos++] = (wxUint8)((float)((col >> 5) & 0x3F) / 63.0f * 255.0f);2318ssimg[sspos++] = (wxUint8)((float)(col & 0x1F) / 31.0f * 255.0f);2319}2320offset_src += info.strideInBytes;2321}2322}2323// Unlock the backbuffer2324grLfbUnlock (GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER);2325wxImage screenshot(image_width, image_height, ssimg);2326screenshot.SaveFile(path, ScreenShotFormats[settings.ssformat].type);2327capture_screen = 0;2328}2329}2330#endif23312332// Capture the screen if debug capture is set2333if (_debugger.capture)2334{2335// Allocate the screen2336_debugger.screen = new wxUint8 [(settings.res_x*settings.res_y) << 1];23372338// Lock the backbuffer (already rendered)2339GrLfbInfo_t info;2340info.size = sizeof(GrLfbInfo_t);2341while (!grLfbLock (GR_LFB_READ_ONLY,2342GR_BUFFER_BACKBUFFER,2343GR_LFBWRITEMODE_565,2344GR_ORIGIN_UPPER_LEFT,2345FXFALSE,2346&info));23472348wxUint32 offset_src=0, offset_dst=0;23492350// Copy the screen2351for (wxUint32 y=0; y<settings.res_y; y++)2352{2353if (info.writeMode == GR_LFBWRITEMODE_8888)2354{2355wxUint32 *src = (wxUint32*)((wxUint8*)info.lfbPtr + offset_src);2356wxUint16 *dst = (wxUint16*)(_debugger.screen + offset_dst);2357wxUint8 r, g, b;2358wxUint32 col;2359for (unsigned int x = 0; x < settings.res_x; x++)2360{2361col = src[x];2362r = (wxUint8)((col >> 19) & 0x1F);2363g = (wxUint8)((col >> 10) & 0x3F);2364b = (wxUint8)((col >> 3) & 0x1F);2365dst[x] = (r<<11)|(g<<5)|b;2366}2367}2368else2369{2370memcpy (_debugger.screen + offset_dst, (wxUint8*)info.lfbPtr + offset_src, settings.res_x << 1);2371}2372offset_dst += settings.res_x << 1;2373offset_src += info.strideInBytes;2374}23752376// Unlock the backbuffer2377grLfbUnlock (GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER);2378}23792380if (fullscreen && debugging)2381{2382debug_keys ();2383debug_cacheviewer ();2384debug_mouse ();2385}23862387if (settings.frame_buffer & fb_read_back_to_screen)2388DrawWholeFrameBufferToScreen();23892390if (fullscreen)2391{2392if (fb_hwfbe_enabled && !(settings.hacks&hack_RE2) && !evoodoo)2393grAuxBufferExt( GR_BUFFER_AUXBUFFER );2394grBufferSwap (settings.vsync);2395fps_count ++;2396if (*gfx.VI_STATUS_REG&0x08) //gamma correction is used2397{2398if (!voodoo.gamma_correction)2399{2400if (voodoo.gamma_table_size && !voodoo.gamma_table_r)2401GetGammaTable(); //save initial gamma tables2402guGammaCorrectionRGB(2.0f, 2.0f, 2.0f); //with gamma=2.0 gamma table is the same, as in N642403voodoo.gamma_correction = 1;2404}2405}2406else2407{2408if (voodoo.gamma_correction)2409{2410if (voodoo.gamma_table_r)2411grLoadGammaTable(voodoo.gamma_table_size, voodoo.gamma_table_r, voodoo.gamma_table_g, voodoo.gamma_table_b);2412else2413guGammaCorrectionRGB(1.3f, 1.3f, 1.3f); //1.3f is default 3dfx gamma for everything but desktop2414voodoo.gamma_correction = 0;2415}2416}2417}24182419if (_debugger.capture)2420debug_capture ();24212422if (fullscreen)2423{2424if (debugging || settings.wireframe || settings.buff_clear || (settings.hacks&hack_PPL && settings.ucode == 6))2425{2426if (settings.hacks&hack_RE2 && fb_depth_render_enabled)2427grDepthMask (FXFALSE);2428else2429grDepthMask (FXTRUE);2430grBufferClear (0, 0, 0xFFFF);2431}2432/* //let the game to clear the buffers2433else2434{2435grDepthMask (FXTRUE);2436grColorMask (FXFALSE, FXFALSE);2437grBufferClear (0, 0, 0xFFFF);2438grColorMask (FXTRUE, FXTRUE);2439}2440*/2441}24422443if (settings.frame_buffer & fb_read_back_to_screen2)2444DrawWholeFrameBufferToScreen();24452446frame_count ++;24472448// Open/close debugger?2449if (CheckKeyPressed(G64_VK_SCROLL, 0x0001))2450{2451if (!debugging)2452{2453//if (settings.scr_res_x == 1024 && settings.scr_res_y == 768)2454{2455debugging = 1;24562457// Recalculate screen size, don't resize screen2458settings.res_x = (wxUint32)(settings.scr_res_x * 0.625f);2459settings.res_y = (wxUint32)(settings.scr_res_y * 0.625f);24602461ChangeSize ();2462}2463}2464else2465{2466debugging = 0;24672468settings.res_x = settings.scr_res_x;2469settings.res_y = settings.scr_res_y;24702471ChangeSize ();2472}2473}24742475// Debug capture?2476if (/*fullscreen && */debugging && CheckKeyPressed(G64_VK_INSERT, 0x0001))2477{2478_debugger.capture = 1;2479}2480}24812482extern "C"2483{24842485/******************************************************************2486Function: ViStatusChanged2487Purpose: This function is called to notify the dll that the2488ViStatus registers value has been changed.2489input: none2490output: none2491*******************************************************************/2492EXPORT void CALL ViStatusChanged (void)2493{2494}24952496/******************************************************************2497Function: ViWidthChanged2498Purpose: This function is called to notify the dll that the2499ViWidth registers value has been changed.2500input: none2501output: none2502*******************************************************************/2503EXPORT void CALL ViWidthChanged (void)2504{2505}25062507#ifdef WINPROC_OVERRIDE2508LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)2509{2510switch (msg)2511{2512case WM_ACTIVATEAPP:2513if (wParam == TRUE && !fullscreen) rdp.window_changed = TRUE;2514break;2515case WM_PAINT:2516if (!fullscreen) rdp.window_changed = TRUE;2517break;25182519/* case WM_DESTROY:2520SetWindowLong (gfx.hWnd, GWL_WNDPROC, (long)oldWndProc);2521break;*/2522}25232524return CallWindowProc(oldWndProc, hwnd, msg, wParam, lParam);2525}2526#endif25272528}25292530int CheckKeyPressed(int key, int mask)2531{2532static Glide64Keys g64Keys;2533if (settings.use_hotkeys == 0)2534return 0;2535#ifdef __WINDOWS__2536return (GetAsyncKeyState(g64Keys[key]) & mask);2537#else2538if (grKeyPressed)2539return grKeyPressed(g64Keys[key]);2540#endif2541return 0;2542}254325442545#ifdef ALTTAB_FIX2546int k_ctl=0, k_alt=0, k_del=0;25472548LRESULT CALLBACK LowLevelKeyboardProc(int nCode,2549WPARAM wParam, LPARAM lParam)2550{2551if (!fullscreen) return CallNextHookEx(NULL, nCode, wParam, lParam);25522553int TabKey = FALSE;25542555PKBDLLHOOKSTRUCT p;25562557if (nCode == HC_ACTION)2558{2559switch (wParam) {2560case WM_KEYUP: case WM_SYSKEYUP:2561p = (PKBDLLHOOKSTRUCT) lParam;2562if (p->vkCode == 162) k_ctl = 0;2563if (p->vkCode == 164) k_alt = 0;2564if (p->vkCode == 46) k_del = 0;2565goto do_it;25662567case WM_KEYDOWN: case WM_SYSKEYDOWN:2568p = (PKBDLLHOOKSTRUCT) lParam;2569if (p->vkCode == 162) k_ctl = 1;2570if (p->vkCode == 164) k_alt = 1;2571if (p->vkCode == 46) k_del = 1;2572goto do_it;25732574do_it:2575TabKey =2576((p->vkCode == VK_TAB) && ((p->flags & LLKHF_ALTDOWN) != 0)) ||2577((p->vkCode == VK_ESCAPE) && ((p->flags & LLKHF_ALTDOWN) != 0)) ||2578((p->vkCode == VK_ESCAPE) && ((GetKeyState(VK_CONTROL) & 0x8000) != 0)) ||2579(k_ctl && k_alt && k_del);25802581break;2582}2583}25842585if (TabKey)2586{2587k_ctl = 0;2588k_alt = 0;2589k_del = 0;2590ReleaseGfx ();2591}25922593return CallNextHookEx(NULL, nCode, wParam, lParam);2594}2595#endif25962597//2598// DllMain - called when the DLL is loaded, use this to get the DLL's instance2599//2600#ifdef OLDAPI2601class wxDLLApp : public wxApp2602{2603public:2604virtual bool OnInit();2605};26062607IMPLEMENT_APP_NO_MAIN(wxDLLApp)26082609bool wxDLLApp::OnInit()2610{2611if (mutexProcessDList == NULL)2612mutexProcessDList = new wxMutex(wxMUTEX_DEFAULT);2613wxImage::AddHandler(new wxPNGHandler);2614wxImage::AddHandler(new wxJPEGHandler);2615return true;2616}26172618#ifndef __WINDOWS__2619int __attribute__ ((constructor)) DllLoad(void);2620int __attribute__ ((destructor)) DllUnload(void);2621#endif26222623// Called when the library is loaded and before dlopen() returns2624int DllLoad(void)2625{2626int argc = 0;2627char **argv = NULL;2628wxEntryStart(argc, argv);2629if (wxTheApp)2630return wxTheApp->CallOnInit() ? TRUE : FALSE;2631return 0;2632}26332634// Called when the library is unloaded and before dlclose() returns2635int DllUnload(void)2636{2637if ( wxTheApp )2638wxTheApp->OnExit();2639wxEntryCleanup();2640return TRUE;2641}26422643#ifdef __WINDOWS__2644extern "C" int WINAPI DllMain (HINSTANCE hinstDLL,2645wxUint32 fdwReason,2646LPVOID lpReserved)2647{2648sprintf (out_buf, "DllMain (%08lx - %d)\n", hinstDLL, fdwReason);2649LOG (out_buf);26502651if (fdwReason == DLL_PROCESS_ATTACH)2652{2653wxSetInstance(hinstDLL);2654return DllLoad();2655}2656else if (fdwReason == DLL_PROCESS_DETACH)2657{2658if (GFXWindow != NULL)2659GFXWindow->SetHWND(NULL);2660return DllUnload();2661}2662return TRUE;2663}26642665void CALL ReadScreen(void **dest, int *width, int *height)2666{2667*width = settings.res_x;2668*height = settings.res_y;2669wxUint8 * buff = (wxUint8*)malloc(settings.res_x * settings.res_y * 3);2670wxUint8 * line = buff;2671*dest = (void*)buff;26722673if (!fullscreen)2674{2675for (wxUint32 y=0; y<settings.res_y; y++)2676{2677for (wxUint32 x=0; x<settings.res_x; x++)2678{2679line[x*3] = 0x20;2680line[x*3+1] = 0x7f;2681line[x*3+2] = 0x40;2682}2683}2684LOG ("ReadScreen. not in the fullscreen!\n");2685return;2686}26872688GrLfbInfo_t info;2689info.size = sizeof(GrLfbInfo_t);2690if (grLfbLock (GR_LFB_READ_ONLY,2691GR_BUFFER_FRONTBUFFER,2692GR_LFBWRITEMODE_565,2693GR_ORIGIN_UPPER_LEFT,2694FXFALSE,2695&info))2696{2697wxUint32 offset_src=info.strideInBytes*(settings.scr_res_y-1);26982699// Copy the screen2700wxUint8 r, g, b;2701if (info.writeMode == GR_LFBWRITEMODE_8888)2702{2703wxUint32 col;2704for (wxUint32 y=0; y<settings.res_y; y++)2705{2706wxUint32 *ptr = (wxUint32*)((wxUint8*)info.lfbPtr + offset_src);2707for (wxUint32 x=0; x<settings.res_x; x++)2708{2709col = *(ptr++);2710r = (wxUint8)((col >> 16) & 0xFF);2711g = (wxUint8)((col >> 8) & 0xFF);2712b = (wxUint8)(col & 0xFF);2713line[x*3] = b;2714line[x*3+1] = g;2715line[x*3+2] = r;2716}2717line += settings.res_x * 3;2718offset_src -= info.strideInBytes;2719}2720}2721else2722{2723wxUint16 col;2724for (wxUint32 y=0; y<settings.res_y; y++)2725{2726wxUint16 *ptr = (wxUint16*)((wxUint8*)info.lfbPtr + offset_src);2727for (wxUint32 x=0; x<settings.res_x; x++)2728{2729col = *(ptr++);2730r = (wxUint8)((float)(col >> 11) / 31.0f * 255.0f);2731g = (wxUint8)((float)((col >> 5) & 0x3F) / 63.0f * 255.0f);2732b = (wxUint8)((float)(col & 0x1F) / 31.0f * 255.0f);2733line[x*3] = b;2734line[x*3+1] = g;2735line[x*3+2] = r;2736}2737line += settings.res_x * 3;2738offset_src -= info.strideInBytes;2739}2740}2741// Unlock the frontbuffer2742grLfbUnlock (GR_LFB_READ_ONLY, GR_BUFFER_FRONTBUFFER);2743}2744LOG ("ReadScreen. Success.\n");2745}2746#endif2747#endif274827492750