⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ggi.cpp

📁 著名SFC模拟器Snes9x的源代码。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. * * (c) Copyright 1996, 1997, 1998 Gary Henderson (gary@daniver.demon.co.uk) and *                                Jerremy Koot (jkoot@euronet.nl) * * Super FX C emulator code  * (c) Copyright 1997, 1998 Lestat (lstat@hotmail.com) and *                          Gary Henderson. * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. * * DSP1 emulator code (c) Copyright 1998 Lestat and Gary Henderson. * DOS port code contains the works of other authors. See headers in * individual files. * * Permission to use, copy, modify and distribute Snes9x in both binary and * source form, for non-commercial purposes, is hereby granted without fee, * providing that this license information and copyright notice appear with * all copies and any derived work. * * This software is provided 'as-is', without any express or implied * warranty. In no event shall the authors be held liable for any damages * arising from the use of this software. * * Snes9x is freeware for PERSONAL USE only. Commercial users should * seek permission of the copyright holders first. Commercial use includes * charging money for Snes9x or software derived from Snes9x. * * The copyright holders request that bug fixes and improvements to the code * should be forwarded to them so everyone can benefit from the modifications * in future versions. * * Super NES and Super Nintendo Entertainment System are trademarks of * Nintendo Co., Limited and its subsidiary companies. */#include <stdlib.h>#include <ctype.h>#include <string.h>#include "snes9x.h"#include "memmap.h"#include "debug.h"#include "ppu.h"#include "snapshot.h"#include "gfx.h"#include "display.h"#include "apu.h"#define NEED_GRAPHTYPE_SYMS#define uint32 ggi_uint32 // Ugly workarount, ggi's unit32 is int, not long...#include <ggi/ggi.h>#undef uint32static ggi_visual_t vis;static ggi_directbuffer_t dbuf;static ggi_pixellinearbuffer *plb = NULL;static int mouse_x = 0;static int mouse_y = 0;static uint32 mouse_buttons = 0;static bool8 superscope = FALSE;static uint32 superscope_turbo = 0;static uint32 superscope_pause = 0;static ggi_mode mode;static bool8 double_buffer; /* Use double_buffering, only for 8 bpp and 16 bpp (565). *//* For double buffering: */static uint32 start_y; /* Start-line of the visible screen */static uint32 framebuffer_screen_size;extern uint32 joypads [5];static void Convert16to8(int width, int height);static void Convert16to15(int width, int height);static void Convert16to16(int width, int height);static void Convert16to24(int width, int height);static void Convert16to32(int width, int height);static void Convert8to8(int width, int height);void S9xDeinitDisplay (){	ggiClose(vis);}static void SetModeType(ggi_graphtype type, bool8 double_height){  mode.frames = 1;  mode.visible.x = IMAGE_WIDTH;  mode.visible.y = IMAGE_HEIGHT;  mode.virt.x = IMAGE_WIDTH;  mode.virt.y = (double_height)?(IMAGE_HEIGHT*2):(IMAGE_HEIGHT);  mode.graphtype = type;  mode.size.x = GGI_AUTO;  mode.size.y = GGI_AUTO;  mode.dpp.x = GGI_AUTO;  mode.dpp.y = GGI_AUTO;}static bool8 InitSixteenBit(void){  SetModeType(GT_16BIT, TRUE);  ggiCheckMode(vis, &mode);  if (mode.graphtype == GT_16BIT) {    mode.virt.y = 2*mode.virt.y;    if (ggiCheckMode(vis, &mode)==0) {      double_buffer = TRUE;      return TRUE;    }    mode.virt.y = mode.virt.y;    if (ggiCheckMode(vis, &mode)==0) {      double_buffer = FALSE;      return TRUE;    }  }  SetModeType(GT_15BIT, FALSE);  if (mode.graphtype == GT_15BIT) {    if (ggiCheckMode(vis, &mode)==0) {      double_buffer = FALSE;      return TRUE;    }  }  SetModeType(GT_32BIT, FALSE);  if (mode.graphtype == GT_32BIT) {     if (ggiCheckMode(vis, &mode)==0) {      double_buffer = FALSE;      return TRUE;    }  }  SetModeType(GT_24BIT, FALSE);  if (mode.graphtype == GT_24BIT) {    if (ggiCheckMode(vis, &mode)==0) {      double_buffer = FALSE;      return TRUE;    }  }    return FALSE; }static bool8 InitEightBit(void){  SetModeType(GT_8BIT, TRUE);  ggiCheckMode(vis, &mode);  if (mode.graphtype == GT_8BIT) {    mode.virt.y = 2*mode.virt.y;    if (ggiCheckMode(vis, &mode)==0) {      double_buffer = TRUE;      return TRUE;    }    mode.virt.y = mode.virt.y;    if (ggiCheckMode(vis, &mode)==0) {      double_buffer = FALSE;      return TRUE;    }  }  return FALSE;}void S9xInitDisplay (int, char **){  if (ggiInit() != 0) {    fprintf(stderr, "unable to initialize libggi, exiting.\n");    S9xExit ();  }  if ((vis=ggiOpen(NULL)) == NULL) {    fprintf(stderr, "unable to open default visual, exiting.\n");    S9xExit ();  }  if (InitSixteenBit()) {    Settings.SixteenBit = TRUE;    if (Settings.ForceNoTransparency) {      Settings.Transparency = FALSE;    } else {      Settings.Transparency = TRUE;    }  } else if (InitEightBit()) {    if (Settings.ForceTransparency) {      fprintf(stderr, "Transparency not supported in 256 color mode.\n");      S9xExit();      Settings.SixteenBit = TRUE;      Settings.Transparency = TRUE;    } else {      Settings.SixteenBit = FALSE;      Settings.Transparency = FALSE;    }  } else {    fprintf(stderr, "Cannot find suitable graphics mode, exiting.\n");    S9xExit ();  }    printf("Opening screen: %dx%d (%dx%d) (%s)\n",	 mode.visible.x, mode.visible.y,	 mode.virt.x, mode.virt.y,	 ggi_graphmask_sym[mode.graphtype+1]);    if (ggiSetMode(vis, &mode) != 0) {    fprintf(stderr, "Cannot open graphic mode!\n");    S9xExit ();  }  ggiSetFlags(vis, GGIFLAG_ASYNC);  if ( ggiDBGetBuffer (vis, &dbuf) ) {    fprintf (stderr, "Error getting display buffer.\n");    S9xExit ();  }  if (ggiDBGetLayout (dbuf) != blPixelLinearBuffer) {    fprintf (stderr, "Error: nonlinear display buffer.\n");    S9xExit ();  }    if ( (plb = ggiDBGetPLB (dbuf)) == NULL) {    fprintf(stderr, "Error getting pixel linear buffer.\n");    S9xExit ();  }  framebuffer_screen_size = plb->stride * mode.visible.y;  if (double_buffer) {    if ( ((mode.graphtype==GT_8BIT) && (plb->setup==sp8a8i8)) ||	 ((mode.graphtype==GT_16BIT) && (plb->setup==sp16a16r5g6b5)) ) {      GFX.Screen = (uint8 *) plb->write + framebuffer_screen_size;      GFX.Pitch =  plb->stride;      GFX.SubScreen = (uint8 *) malloc (plb->stride * mode.visible.y );            start_y = 0;      ggiSetOrigin(vis, 0, start_y);    } else {      fprintf(stderr, "Wrong buffer type, fallback to non double_buffer\n");      double_buffer = FALSE;    }  }  if (!double_buffer) {    GFX.Screen = (uint8 *) malloc (plb->stride * mode.visible.y );    GFX.Pitch =  plb->stride;    GFX.SubScreen = (uint8 *) malloc (plb->stride * mode.visible.y );  }}void S9xPutImage (int width, int height){  if (double_buffer) {    if (start_y == 0) {       start_y = mode.visible.y;      GFX.Screen = (uint8 *) plb->write;    } else {      start_y = 0;      GFX.Screen = (uint8 *) plb->write + framebuffer_screen_size;    }        GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1;        ggiSetOrigin(vis, 0, start_y);  } else {    if (Settings.SixteenBit) {      /* 16 bpp source */      switch (mode.graphtype) {      case GT_8BIT:	Convert16to8(width, height);	break;      case GT_15BIT:	Convert16to15(width, height);	break;      case GT_16BIT:	Convert16to16(width, height);	break;      case GT_24BIT:	Convert16to24(width, height);	break;      case GT_32BIT:	Convert16to32(width, height);	break;      default:	break;      }    } else {      /* 8 bpp source */      switch (mode.graphtype) {      case GT_8BIT:	Convert8to8(width, height);	break;      default:	break;      }    }  }    ggiFlush(vis);}void S9xSetTitle (const char *string){}bool8 S9xReadMousePosition (int which1, int &x, int &y, uint32 &buttons){    if (which1 == 0)    {      x = mouse_x;      y = mouse_y;      buttons = mouse_buttons;      return (TRUE);    }    return (FALSE);}bool8 S9xReadSuperScopePosition (int &x, int &y, uint32 &buttons){  x = mouse_x;  y = mouse_y;  buttons = (mouse_buttons & 3) | (superscope_turbo << 2) |    (superscope_pause << 3);  return (TRUE);}void S9xProcessEvents (bool8 block){  ggi_event ev;  struct timeval tv = {0,0};  ggi_event_mask mask;  uint32 keysym;    if ((!block) && ((mask=ggiEventPoll(vis, emAll, &tv))==0)) {    return;  }  do {    ggiEventRead(vis, &ev, emAll);        uint8 byte1 = 0;    uint8 byte2 = 0;    uint8 byte3 = 0;    uint8 byte4 = 0;	    switch(ev.any.type) {    case evKeyRepeat:      break;    case evKeyPress:    case evKeyRelease:      keysym = ev.key.sym;      switch ( keysym) {      case 'k':      case GGI_KEY_RIGHT:	byte2 = 1;	break;      case 'h':      case GGI_KEY_LEFT:	byte2 = 2;	break;      case 'j':      case 'n':      case GGI_KEY_DOWN:	byte2 = 4;	break;      case 'u':      case GGI_KEY_UP:		byte2 = 8;	break;      case GGI_KEY_RETURN:	byte2 = 16;	break; // Start      case ' ':	byte2 = 32;	break; // Select      case '.':      case 't':      case 'd':		byte1 = 128;	break; // A      case '/':      case 'y':      case 'c':		byte2 = 128;	break; // B

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -