📄 dgenw.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 + -