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

📄 dgenw.cpp

📁 DGen源码最后版本
💻 CPP
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <mmsystem.h>
#include <ddraw.h>
#include "md/md.h"
#include "md/fm.h"
#include "d.h"

// DGen Windows Directx (1.11+)
static char temp[0x1000]="";

static wconsole *wcon=0;
static HWND console_win=0;
static HWND md_win=0;
static dxdisp *md_win_disp=0;
static int md_win_active=1,app_active=1;
md *megad=0;

struct prof_node {int count; char *name; struct prof_node *next; };

static struct prof_node *prof_list=NULL;
static int prof_total=0;

static signed short *sndbuf[2]={NULL,NULL};
extern int snd_size,snd_rate,stereo16;
int sound_is_okay=0;
static int fullscreen=0,use_dsound=1;
#define OKAY_TO_DRAW_GRAPHICS \
((fullscreen&&md_win_active&&app_active)||(!fullscreen))

static int time_id=0;
static int last_timer=0; 
static volatile int timer=0;
static int everything_init(HINSTANCE hinst);
static int everything_exit();

extern char dest_name[0x1000];
extern int dest_port;

static int dvprintf(char *format,va_list arg)
{
  static int reentry=0;
  if (reentry) return 1; reentry=1;

  if (wcon)
  {
    vsprintf (temp,format,arg);
    wcon->puts(temp,0);
  }
  else if (0)
  {
    FILE *hand=fopen("zzdebug.txt","at");
    if (hand!=NULL)
    { vfprintf (hand,format,arg); fclose(hand); }
  }

  reentry=0; return 0;
}

extern "C" int dprintf(char *format, ...)
{
  static int reentry=0;
  if (reentry) return 1; reentry=1;

  va_list arg;
  va_start(arg,format);

  dvprintf (format,arg);

  va_end(arg);

  reentry=0; return 0;
}

static int update_megadrive();
void CALLBACK timer_callback(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
  static int reentry=0; if (reentry) return; reentry=1;
  timer++;

  {
    struct prof_node *chk;
    chk=prof_list; // Search for prof_name in our list
    while (chk!=NULL)
    {
      if (prof_name==chk->name) break;
      chk=chk->next;
    }

    if (chk==NULL) // not in our list so add it
    {
      struct prof_node *n;
      n=new struct prof_node;
      if (n)
      {
        n->name=prof_name; n->count=0;
        n->next=prof_list; chk=prof_list=n;
      }
    }
    if (chk!=NULL) { chk->count++; prof_total++; }
  }

  reentry=0;
}

static int prof_reset() // doubles as prof_cleanup
{
  prof_total=0;
  while (prof_list!=NULL)
  {
    struct prof_node *rel; rel=prof_list;
    prof_list=prof_list->next;
    // now delete this separated node
    free(rel);
  }
  dprintf ("prof_reset()\n");
  return 0;
}

LRESULT CALLBACK dgen_console_proc
  (HWND wnd,UINT cmd,WPARAM wparam,LPARAM lparam)
{
  if (wcon) return wcon->proc(cmd,wparam,lparam);

  // Let windows handle everything else
  return DefWindowProc(wnd,cmd,wparam,lparam);
}                                     

static int dgen_console_register(HINSTANCE hinst)
{
  static WNDCLASS wclass;
  memset(&wclass,0,sizeof(wclass));
  wclass.style = 0; //CS_HREDRAW | CS_VREDRAW;
  wclass.lpszClassName="dgen_console";
  wclass.hInstance=hinst;
  wclass.lpfnWndProc=dgen_console_proc;
  wclass.hbrBackground=GetStockObject(BLACK_BRUSH);
  wclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  RegisterClass(&wclass);
  return 0;
}


static int our_sound_init()
{
  int ret=0,i;
  sndbuf[0]=(signed short *)malloc(snd_size*sizeof(signed short));
  if (sndbuf[0]==NULL) return 1;
  sndbuf[1]=(signed short *)malloc(snd_size*sizeof(signed short));
  if (sndbuf[1]==NULL) return 1;

  memset(sndbuf[0],0,snd_size*sizeof(signed short));
  memset(sndbuf[1],0,snd_size*sizeof(signed short));

// Dave fiddling (3 chips)
  ret=YM2612Init(3,8000000L*94/100,snd_rate,NULL,NULL);
  if (ret!=0) dprintf ("YM2612Init returned %d\n",ret);

  ret=SN76496_init(0,3750000L*94/100,snd_rate,16);
  if (ret!=0) dprintf ("SN76496_init returned %d\n",ret);
  sound_is_okay=1;
  return 0;
}

static int our_sound_exit()
{
  sound_is_okay=0;
  YM2612Shutdown();
  if (sndbuf[0]!=NULL) free(sndbuf[0]); sndbuf[0]=NULL;
  if (sndbuf[1]!=NULL) free(sndbuf[1]); sndbuf[1]=NULL;
  return 0;
}

static int update_megadrive()
{
  struct sndinfo si; struct bmap bm;
  if (megad==0) return 1;
  si.l=sndbuf[0]; si.r=sndbuf[1]; si.len=snd_size;

  if (md_win_active)
    get_megad_pad(megad->pad,0);
  else
    get_megad_pad(megad->pad,1); // no keys, joystick only


  if (use_dsound)
  {
    if (directsound_need()==0) return 0;
    while (directsound_need()==1)
    {
      megad->one_frame(NULL,NULL,&si);
      directsound_give(sndbuf);
    }

    if (OKAY_TO_DRAW_GRAPHICS)
    {
      if (md_win_disp==0) return 1;
      bm=md_win_disp->lock();
      if (bm.data!=NULL)
      {
        megad->one_frame(&bm,NULL,&si);
        md_win_disp->unlock();
        directsound_give(sndbuf);
        md_win_disp->update();
      }
    }
    else
    {
      megad->one_frame(NULL,NULL,&si);
      directsound_give(sndbuf);
    }
  }
  else
  {
    int catch_up=0,i,aim_for=0;
    int gone=0,t;

    aim_for=timer;
    catch_up=aim_for-last_timer; if (catch_up>10) catch_up=10;
    for (i=0;i<catch_up-1;i++)
    {
      megad->one_frame(NULL,NULL,&si);
      last_timer++;
    }
    if (last_timer+1 == aim_for)
    {
      bm=md_win_disp->lock();
      if (bm.data!=NULL)
      {
        megad->one_frame(&bm,NULL,&si);
        md_win_disp->unlock();
        md_win_disp->update();
      }
      last_timer++;
    }
  }

  return 0;
}

static int load()
{
  extern char rom_name[0x800];
  extern int get_rom_name();
  if (megad==0) return 1;
  directsound_silence();
  if (get_rom_name()==0)
  {
    our_sound_exit();
    megad->load(rom_name,1);
    our_sound_init();
    last_timer=timer;
    // otherwise it skips the time we were selecting the file
  }
  return 0;
}


static char *check_for(char *cmd,char *var)
{
  int ln;
  ln=strlen(var);
  if (strncmp(cmd,var,ln)==0) return cmd+ln;
  return NULL;
}

int dgen_console_proc(char *cmd,console *con)
{
  char *v; int parse=0;
#define DVAR(x)if (v=check_for(cmd,#x"=")) { x=atoi(v); return 0; }\
  if (v=check_for(cmd,"print "))\
  if (check_for(v,#x)) { dprintf (#x" is %d\n",x); return 0; }

#define SVAR(x)if (v=check_for(cmd,#x"=")) { strcpy(x,v); return 0; }\
  if (v=check_for(cmd,"print "))\
  if (check_for(v,#x)) { dprintf (#x" is %s\n",x); return 0; }

  DVAR(dest_port)
  SVAR(dest_name)

  if (cmd[0]=='\'') {net_client(cmd+1); return 0;}
  if (v=check_for(cmd,"net.init")) { net_init(); return 0; }
  if (v=check_for(cmd,"net.exit")) { net_exit(); return 0; }
  if (check_for(cmd,"quit")) { PostQuitMessage(0); return 0; }
  if (v=check_for(cmd,"server"))
    { net_server(md_win,atoi(v)); return 0; }
  if (v=check_for(cmd,"client"))
  {
    if (v[0]) net_client(v+1); else net_client(NULL);
    return 0;
  }
  if (v=check_for(cmd,"input"))
  {
    extern int common_keys(int type); // In MDINP.CPP
    common_keys(atoi(v)); return 0;
  }
  if (v=check_for(cmd,"destroy"))
  { DestroyWindow(md_win); }
  if (v=check_for(cmd,"load"))
  { if (v[0]) { if (megad) megad->load(v+1,1); } else load(); return 0; }
  if (v=check_for(cmd,"free"))
  { if (megad) megad->unplug(); return 0; }
  if (v=check_for(cmd,"reset"))
  { if (megad) megad->reset(); return 0; }
  if (v=check_for(cmd,"line"))
  { if (megad) megad->render_method=(megad->render_method+1)%3; return 0; }
  if (v=check_for(cmd,"prof"))
  {
    float mult=1.0; char *af;
    struct prof_node *p;

    if (check_for(v,".reset"))
      prof_reset();

    if (af=check_for(v,"/"))
    { mult=atof(af); if (mult>0.1) mult=100.0/mult; }

    dprintf ("Profiling info:\n");
    p=prof_list;
    while (p!=NULL && prof_total)
    {
      dprintf (" (%7d) %6.2f%% %s\n",p->count,
        (float)p->count*100*mult/(float)prof_total,
        p->name);
      p=p->next;
    }
    return 0;
  }
  if (v=check_for(cmd,"reg"))
  {
    int n=0; n=strtol(v,NULL,0);
    n&=0x1f;
    if (megad) dprintf ("vdp reg[%.2x (%2d)] = %.2x\n",n,n,megad->vdp.reg[n]);
    return 0;
  }
  if (v=check_for(cmd,"cpuemu"))
  { if (megad) megad->change_cpu_emu(atoi(v)); return 0; }
  if ( v=check_for(cmd,"mjazz"))
  if ( megad )
  {
    if (v[0]==0) megad->mjazz=!megad->mjazz;
    else megad->mjazz=atoi(v);
    dprintf ("mjazz set to %d\n",megad->mjazz);
    megad->flush_fm_to_mame();
    return 0;
  }
  con->puts("Command Unknown\n",2);
  return 1;
}

LRESULT CALLBACK md_win_proc
  (HWND wnd,UINT cmd,WPARAM wparam,LPARAM lparam)
{
  int ret=0;


  if (cmd==WM_CREATE)
  {
    if (md_win_disp==0) md_win_disp=new dxdisp(wnd,fullscreen);
  }

  if (cmd==WM_PAINT||cmd==WM_NCPAINT)
  {
    if (md_win_disp) md_win_disp->paint();
  }

  if (cmd==WM_CLOSE)
  {
    PostQuitMessage(0);
  }

  if (cmd==WM_DESTROY)
  {
    delete md_win_disp; md_win_disp=0;
  }

  if (cmd==WM_ACTIVATE)    md_win_active=wparam;
  if (cmd==WM_ACTIVATEAPP) app_active=wparam;

  // Let net.cpp handle Internet packets
  if (cmd>=WM_USER && cmd<WM_USER+65536)
  {
    net_recv(cmd-WM_USER);
    return 0;
  }


  return DefWindowProc(wnd,cmd,wparam,lparam);
}                                     



int md_win_register(HINSTANCE hinst)
{
  static WNDCLASS wclass;
  memset(&wclass,0,sizeof(wclass));
  wclass.style = 0; //CS_HREDRAW | CS_VREDRAW;
  wclass.lpszClassName="md_win";
  wclass.hInstance=hinst;
  wclass.lpfnWndProc=md_win_proc;
  wclass.hbrBackground=GetStockObject(BLACK_BRUSH);
  wclass.hCursor = LoadCursor(NULL, IDC_ARROW);
//  wclass.lpszMenuName = "NETPMENU";  // Name of menu resource in .RC file.
  RegisterClass(&wclass);
  return 0;
}

static int everything_init(HINSTANCE hinst)
{
  int conx=52,cony=15;

  if (!fullscreen)
  {
    // INIT CONSOLE (do it first so we can see what's happening)
    console_win=CreateWindow
    (
      "dgen_console","DGen v"VER" Console",
      WS_OVERLAPPEDWINDOW,
      80,200,conx*8+8,(cony+1)*15+30,
      0,0,hinst,0
    );
    wcon=new wconsole(console_win,conx,cony);
    wcon->cmd_proc=dgen_console_proc;
    wcon->puts("DGen v"VER" Console\n",3);
    ShowWindow(console_win,SW_NORMAL);
  }

  // INIT MD SCREEN WINDOW
  md_win=CreateWindow
  (
    "md_win","DGen v" VER,
    WS_OVERLAPPEDWINDOW,
    80,40,320*2+8,224*2+21+4,0,0,hinst,0
  );
  ShowWindow(md_win,SW_NORMAL);
  if (fullscreen) ShowCursor(FALSE);

  // INIT DIRECTINPUT
  directinput_init(hinst,md_win);

  // INIT DIRECTSOUND
  // (Seems to like md_win, the DSound window, to be active)
  SetFocus(md_win);
  directsound_init(md_win);
    our_sound_init();
  if (megad) megad->flush_fm_to_mame();

  time_id=timeSetEvent(1000/60,1000/60,timer_callback,0,TIME_PERIODIC);
  dprintf ("timeSetEvent returned %x\n",time_id);
  return 0;
}

static int everything_exit()
{
  // EXIT CONSOLE (may as well since we won't see any error messages
  if (console_win) DestroyWindow(console_win); console_win=0;
  if (wcon) delete wcon; wcon=0;

  timeKillEvent(time_id);

  // EXIT DIRECTSOUND
    our_sound_exit();
  directsound_exit();

  // EXIT DIRECTINPUT
  directinput_exit();

  if (fullscreen) ShowCursor(TRUE);
  // EXIT MD SCREEN WINDOW
  if (md_win) DestroyWindow(md_win);
  md_win=0;

  return 0;
}

int WINAPI WinMain
  (HINSTANCE hinst,HINSTANCE prev_inst,LPSTR cmd_line,int show_code)
{
  int ret=0,done=0;
  MSG msg;

  dgen_console_register(hinst);
  md_win_register(hinst);

  megad=new md;
  if (megad==0) exit(1);
  {
    extern int load_config(md *megad);
    load_config(megad);
  }

  everything_init(hinst);

  if (wcon) wcon->update();

  if (cmd_line==NULL) load();
  else if (cmd_line[0]) megad->load(cmd_line,1);
  else load();

  while (!done)
  {
    static int toggle_fullscreen=0;
    if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
    {
      if (msg.message==WM_SYSKEYDOWN)
        if (msg.wParam==0xd) toggle_fullscreen=1;

      if (msg.message == WM_QUIT) done=1;
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
    else
    {
      if (toggle_fullscreen)
      {
        everything_exit(); fullscreen=!fullscreen; everything_init(hinst);
      }
      toggle_fullscreen=0;
      PROFS("update_megadrive")
      update_megadrive();
      PROFE
      if (wcon) wcon->update();
    }
  }

  everything_exit();
  prof_reset(); // clean up

  if (megad)
  {
    extern int unload_config(md *megad);
    unload_config(megad);
  }

  if (megad) delete megad; megad=0;

  return 0;
}

⌨️ 快捷键说明

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