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

📄 guicore.cpp

📁 NES game Emulator in Linux.c and asm codes.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*

SNEeSe, an Open Source Super NES emulator.


Copyright (c) 1998-2004 Charles Bilyue'.
Portions Copyright (c) 2003-2004 Daniel Horchner.

This is free software.  See 'LICENSE' for details.
You must read and accept the license prior to use.

*/

/*

 GUIcore.cc
  Contains most (eventually all) GUI core code - emulator specific GUI code
   plugs into this!
  Some stuff from helper.c will be moved here!

  This GUI has been mostly rewritten to have two parts:
   GUI core code
   Emulator specific GUI code

  The core has been written in C++, taking advantage of OOP to a
   great extent - however, in its current state, it is far from
   portable.

  The core primarily consists of a few basic classes:
   CTL
    a generic GUI 'control', which relies on four basic methods:
     attach() - init code when control is attached to a WINDOW
     detach() - deinit code when control is detached from its WINDOW
     refresh() - refresh the visual appearance of the control
     process() - periodic maintenance routine, which will eventually
      be able to respond to messages passed in from the core
    all four methods are defined virtual with no bodies in the CTL
     class definition
   WINDOW - associates an object with an area of the screen, and allows
    CTLs to link to that object and screen area
*/

#include <stdio.h>
#include <stdlib.h>

#include "wrapaleg.h"
#include "guicore.h"

/* ------------------------- DIRECTORY STUFF ------------------------- */

#include <unistd.h>
#include <string.h>

EXTERN char start_dir[MAXPATH]; /* defined in dos.c */

unsigned char GUI_ENABLED;
const char *GUI_error_table[] =
{
 "Continue",
 "Normal exit",
 "Screen setup failure",
 "Memory allocation failure"
};

int max_listed_files = 1024;

FILELIST *DirList;

int fncmp(const FILELIST *f1, const FILELIST *f2){
 if (f2->Directory && !f1->Directory) return -1;
 if (f1->Directory && !f2->Directory) return 1;
 return stricmp(f1->Name, f2->Name);
}

// This fills an array of FILELIST with file information
// from the path given, starting at file number Offset
// and with a maximum number of files of max_listed_files

int GetDirList(char *Path, FILELIST *&Files, int Offset){
 al_ffblk FileInfo;
 int FilesRead;

 int done = al_findfirst(Path, &FileInfo, FA_ARCH | FA_DIREC | FA_RDONLY);
 if (done)
 {
  al_findclose(&FileInfo);
  return 0;    // empty dir returns 0
 }

 strcpy(Files[0].Name, "..");
 // Small dirs are 4096 bytes in size on GNU/Linux, haven't tried other OS'es.
 //  Is file size for dirs important?
 Files[0].Size = 4096;
 Files[0].Directory = FA_DIREC;
 FilesRead = 1;

 do {
  if (FilesRead == max_listed_files - 26)
  {
   FILELIST *tempFiles;

   tempFiles = (FILELIST *) realloc(Files, sizeof(FILELIST[max_listed_files += 128]));
   if (!tempFiles)
   {
    set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
    printf("Fatal error: Failure allocating memory for directory\n");
    exit(EXIT_FAILURE);
   }
   else
   {
    Files = tempFiles;
   }
  }

  if (strcmp(".", FileInfo.name) != 0 && strcmp("..", FileInfo.name) != 0){
   strcpy(Files[FilesRead].Name, FileInfo.name);
   Files[FilesRead].Size = FileInfo.size;
   Files[FilesRead].Directory = FileInfo.attrib & FA_DIREC;
   FilesRead++;
  }
  done = al_findnext(&FileInfo);
 } while (!done);   // while more files and more wanted

 al_findclose(&FileInfo);

 // Sort starting one entry after the entry for ".."
 qsort(&Files[1], FilesRead - 1, sizeof(FILELIST),
  (int (*)(const void *,const void *))fncmp);

#if defined(ALLEGRO_DOS) || defined(ALLEGRO_WINDOWS)
 for (int a = 0; a < 26; a++){
  sprintf(Files[FilesRead].Name, "%c:", a + 'A');
  Files[FilesRead].Size = 0;
  Files[FilesRead].Directory = FA_DIREC;
  FilesRead++;
 }
#endif

 return FilesRead;
}

/* ------------------------- GUI STUFF ------------------------- */

#include "romload.h"
#include "types.h"
#include "font.h"
#include "helper.h"

RGB GUIPal[16]={{ 0, 0, 0, 0},{ 0, 0,31, 0},{ 0,31, 0, 0},{ 0,31,31, 0},
                {31, 0, 0, 0},{31, 0,31, 0},{39,23, 0, 0},{47,47,47, 0},
                {31,31,31, 0},{ 0, 0,63, 0},{ 0,63, 0, 0},{ 0,63,63, 0},
                {63, 0, 0, 0},{63, 0,63, 0},{63,63, 0, 0},{63,63,63, 0}};

GUI_FONT ZSNES_Font(
 Xlat_ZSNES_6x6,Font_ZSNES_6x6,
 Font_Width_ZSNES,Font_Height_ZSNES,
 Font_WidthSpace_ZSNES,Font_HeightSpace_ZSNES);

GUI_FONT Modified_Font(
 Xlat_ZSNES_6x6,Font_Modified_6x6,
 Font_Width_ZSNES,Font_Height_ZSNES,
 Font_WidthSpace_ZSNES,Font_HeightSpace_ZSNES);

GUI_FONT Old_Font(
 Xlat_6x8,Font_6x8,
 Font_Width_Old,Font_Height_Old,
 Font_WidthSpace_Old,Font_HeightSpace_Old);

GUI_FONT *default_font=&Modified_Font;

int GUI_ScreenWidth=320,GUI_ScreenHeight=240;
BITMAP *GUI_Bitmap=0;
unsigned char *GUI_Screen;

static char err_create_scrn_buf[]="Error creating GUI screen buffer.\n";

char *GUI_core_init(){
 DirList = (FILELIST *) malloc(sizeof(FILELIST[max_listed_files]));
 GUI_Bitmap=create_bitmap_ex(8,GUI_ScreenWidth,GUI_ScreenHeight);
 if(!GUI_Bitmap) return err_create_scrn_buf;
 clear(GUI_Bitmap);
 GUI_Screen=(unsigned char *)GUI_Bitmap->dat;
 return 0;
}

void CopyGUIScreen(){
 acquire_screen();

 blit(Allegro_Bitmap,screen,0,0,0,0,ScreenX,ScreenY);

 release_screen();
}

int WINDOW::add(CTL *control){
 if ((numctls + 1) == 0) return control->handle = 0;
 CTL *temp = 0, *last = 0;
 unsigned handle = 1;

 if (!first){
  first = control;
 } else {
  for (temp = first; temp; temp = (last = temp)->next){
   if (temp->handle == handle){
    handle++; if (!handle) return control->handle = 0; temp = first;
   }
  }
  last->next=control;
 }

 numctls++; control->next = 0; control->attach(this);
 return control->handle = handle;
}

int WINDOW::sub(unsigned handle){
 int found = 0;
 CTL *temp, *last;

 if (first){
  while (first->handle == handle){
    found = -1;
    numctls--;
    first = first->next;
    first->detach(this);
  }

  last = first;
  for (temp = first->next; temp; temp = (last = temp)->next){
   while (temp->handle == handle){
    found = -1;
    numctls--;
    last->next = temp->next;
    temp->detach(this);
   }
  }
 }

 return found;
}

void WINDOW::refresh(){ refresh((WINDOW *)0); };
void WINDOW::refresh(WINDOW *parent){
 CTL::refresh(parent);
 rewind();
 CTL *control;
 while((control = next()) != 0){
  control->refresh(this);
 }
}

void CTL_CLEAR::refresh(WINDOW *parent){
 CTL::refresh(parent);
 int x = parent->get_visible_x(), width = parent->get_width();
 int y = parent->get_visible_y(), height = parent->get_height();

 if (parent->get_visible_x() < 0){ width += x; x = 0; }
 if (x + width > GUI_ScreenWidth) width = GUI_ScreenWidth - x;
 if (parent->get_visible_y() < 0){ height += y; y = 0; }
 if (y + height > GUI_ScreenHeight) height = GUI_ScreenHeight - y;

 if (height > 0) for (int v = y; v < y + height; v++){
  if (width > 0) memset(GUI_Screen + x + GUI_ScreenWidth * v, color, width);
 }
}

void CTL_BORDER::refresh(WINDOW *parent){
 CTL::refresh(parent);
 const int
  cBorder_TL=240+15,cBorder_T=240+15,cBorder_TR=240+7,
  cBorder_L =240+15,cBorder_R=240+ 8,
  cBorder_BL=240+ 7,cBorder_B=240+ 8,cBorder_BR=240+8;

 if(parent->get_x()>=GUI_ScreenWidth ||
  parent->get_y()>=GUI_ScreenHeight) return;

 // left/middle/right, outer/inner, x position/width
 int lox,low,mox,mow,rox,row;
 int lix,liw,mix,miw,rix,riw;
 lox=parent->get_x(); low=1;
 lix=lox+low; liw=1;
 mox=lox+low; mow=parent->get_width()+parent->get_gap_x()+liw*2;
 mix=lix+liw; miw=parent->get_width()+parent->get_gap_x();
 rox=mox+mow; row=1;
 rix=mix+miw; riw=1;

 if(lox<0){ low+=lox; lox=0; }
 if((lox+low)>GUI_ScreenWidth) low=GUI_ScreenWidth-lox;
 if(mox<0){ mow+=mox; mox=0; }
 if((mox+mow)>GUI_ScreenWidth) mow=GUI_ScreenWidth-mox;
 if(rox<0){ row+=rox; rox=0; }
 if((rox+row)>GUI_ScreenWidth) row=GUI_ScreenWidth-rox;
 if(lix<0){ liw+=lix; lix=0; }
 if((lix+liw)>GUI_ScreenWidth) liw=GUI_ScreenWidth-lix;
 if(mix<0){ miw+=mix; mix=0; }
 if((mix+miw)>GUI_ScreenWidth) miw=GUI_ScreenWidth-mix;
 if(rix<0){ riw+=rix; rix=0; }
 if((rix+riw)>GUI_ScreenWidth) riw=GUI_ScreenWidth-rix;

 // top/middle/bottom, outer/inner, y position/height
 int toy,toh,moy,moh,boy,boh;
 int tiy,tih,miy,mih,biy,bih;
 toy=parent->get_y(); toh=1;
 tiy=toy+toh; tih=1;
 moy=toy+toh; moh=parent->get_height()+parent->get_gap_y()+tih*2;
 miy=tiy+tih; mih=parent->get_height()+parent->get_gap_y();
 boy=moy+moh; boh=1;
 biy=miy+mih; bih=1;

 if(toy<0){ toh+=toy; toy=0; }
 if((toy+toh)>GUI_ScreenHeight) toh=GUI_ScreenHeight-toy;
 if(moy<0){ moh+=moy; moy=0; }
 if((moy+moh)>GUI_ScreenHeight) moh=GUI_ScreenHeight-moy;
 if(boy<0){ boh+=boy; boy=0; }
 if((boy+boh)>GUI_ScreenHeight) boh=GUI_ScreenHeight-boy;

⌨️ 快捷键说明

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