rm old windows port

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@805 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2009-10-05 19:26:42 +00:00
parent 823b9004c4
commit 91842de3ea
12 changed files with 0 additions and 1921 deletions

View file

@ -1,148 +0,0 @@
#include "app.h"
#ifndef _XBOX
#pragma warning (disable:4201)
#include <mmsystem.h>
#include <dsound.h>
#endif
static IDirectSound *DSound=NULL;
static IDirectSoundBuffer *LoopBuffer=NULL;
static int LoopLen=0,LoopWrite=0; // Next position in loop to write
short *DSoundNext=NULL; // Buffer for next sound data to put in loop
static int LoopBlank()
{
void *mema=NULL,*memb=NULL;
DWORD sizea=0,sizeb=0;
LoopBuffer->Lock(0,LoopLen<<((PicoOpt&8) ? 2 : 1), &mema,&sizea, &memb,&sizeb, 0);
if (mema) memset(mema,0,sizea);
LoopBuffer->Unlock(mema,sizea, memb,sizeb);
return 0;
}
int DSoundInit()
{
DSBUFFERDESC dsbd;
WAVEFORMATEX wfx;
memset(&dsbd,0,sizeof(dsbd));
memset(&wfx,0,sizeof(wfx));
// Make wave format:
wfx.wFormatTag=WAVE_FORMAT_PCM;
wfx.nChannels=(unsigned short)((PicoOpt&8) ? 2 : 1); // Stereo/mono
wfx.nSamplesPerSec=PsndRate;
wfx.wBitsPerSample=16;
wfx.nBlockAlign=(WORD)((wfx.nChannels*wfx.wBitsPerSample)>>3);
wfx.nAvgBytesPerSec=wfx.nBlockAlign*wfx.nSamplesPerSec;
// Make buffer for the next seg to put into the loop:
DSoundNext=(short *)malloc((PsndLen<<2)+64); if (DSoundNext==NULL) return 1;
memset(DSoundNext,0,PsndLen<<2);
// lprintf("p %p\n", DSoundNext);
// Create the DirectSound interface:
DirectSoundCreate(NULL,&DSound,NULL);
if (DSound==NULL) return 1;
LoopLen=PsndLen<<1; // 2 segs
#ifndef _XBOX
LoopLen<<=1; // 4 segs
DSound->SetCooperativeLevel(FrameWnd,DSSCL_PRIORITY);
dsbd.dwFlags=DSBCAPS_GLOBALFOCUS; // Play in background
#endif
// Create the looping buffer:
dsbd.dwSize=sizeof(dsbd);
dsbd.dwBufferBytes=LoopLen<<wfx.nChannels; // 16bit stereo?
dsbd.lpwfxFormat=&wfx;
DSound->CreateSoundBuffer(&dsbd,&LoopBuffer,NULL);
if (LoopBuffer==NULL) return 1;
LoopBlank();
LoopBuffer->Play(0,0,DSBPLAY_LOOPING);
return 0;
}
void DSoundExit()
{
if (LoopBuffer) LoopBuffer->Stop();
RELEASE(LoopBuffer)
RELEASE(DSound)
DSound=0;
if (DSoundNext) free(DSoundNext); DSoundNext=NULL;
}
static int WriteSeg()
{
void *mema=NULL,*memb=NULL;
DWORD sizea=0,sizeb=0;
int ret;
// Lock the segment at 'LoopWrite' and copy the next segment in
ret = LoopBuffer->Lock(LoopWrite<<((PicoOpt&8) ? 2 : 1),PsndLen<<((PicoOpt&8) ? 2 : 1), &mema,&sizea, &memb,&sizeb, 0);
if (ret) lprintf("LoopBuffer->Lock() failed: %i\n", ret);
if (mema) memcpy(mema,DSoundNext,sizea);
// if (memb) memcpy(memb,DSoundNext+sizea,sizeb);
if (sizeb != 0) lprintf("sizeb is not 0! (%i)\n", sizeb);
ret = LoopBuffer->Unlock(mema,sizea, memb,0);
if (ret) lprintf("LoopBuffer->Unlock() failed: %i\n", ret);
return 0;
}
static int DSoundFake()
{
static int ticks_old = 0;
int ticks = GetTickCount() * 1000;
int diff;
diff = ticks - ticks_old;
if (diff >= 0 && diff < 1000000/60*4)
{
while (diff >= 0 && diff < 1000000/60)
{
Sleep(1);
diff = GetTickCount()*1000 - ticks_old;
}
ticks_old += 1000000/60;
}
else
ticks_old = ticks;
return 0;
}
int DSoundUpdate()
{
DWORD play=0;
int pos=0;
if (LoopBuffer==NULL) return DSoundFake();
LoopBuffer->GetCurrentPosition(&play,NULL);
pos=play>>((PicoOpt&8) ? 2 : 1);
// 'LoopWrite' is the next seg in the loop that we want to write
// First check that the sound 'play' pointer has moved out of it:
if (pos>=LoopWrite && pos<LoopWrite+PsndLen) return 1; // No, it hasn't
WriteSeg();
// Advance LoopWrite to next seg:
LoopWrite+=PsndLen; if (LoopWrite+PsndLen>LoopLen) LoopWrite=0;
return 0;
}

View file

@ -1,423 +0,0 @@
#include "app.h"
#ifdef USE_D3D
// d3d
static IDirect3D8 *Direct3D=NULL;
IDirect3DDevice8 *Device=NULL;
IDirect3DSurface8 *DirectBack=NULL; // Back Buffer
static IDirect3DVertexBuffer8 *VertexBuffer=NULL;
struct CustomVertex
{
float x,y,z; // Vertex cordinates
unsigned int colour;
float u,v; // Texture coordinates
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
static CustomVertex VertexList[4];
#endif
// ddraw
#include <ddraw.h>
LPDIRECTDRAW7 m_pDD = NULL;
LPDIRECTDRAWSURFACE7 m_pddsFrontBuffer = NULL;
LPDIRECTDRAWSURFACE7 m_pddsBackBuffer = NULL;
// quick and dirty stuff..
static void DirectExitDDraw()
{
RELEASE(m_pddsBackBuffer);
RELEASE(m_pddsFrontBuffer);
RELEASE(m_pDD);
}
static int DirectDrawInit()
{
HRESULT ret;
LPDIRECTDRAWCLIPPER pcClipper = NULL;
DDSURFACEDESC2 ddsd;
ret = DirectDrawCreateEx(NULL, (VOID**)&m_pDD, IID_IDirectDraw7, NULL);
if (ret) { LOGFAIL(); return 1; }
// Set cooperative level
ret = m_pDD->SetCooperativeLevel( FrameWnd, DDSCL_NORMAL );
if (ret) { LOGFAIL(); goto fail; }
// Create the primary surface
ZeroMemory( &ddsd, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
ret = m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer, NULL );
if (ret) { LOGFAIL(); goto fail; }
// Create the backbuffer surface
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = EmuWidth;
ddsd.dwHeight = EmuHeight;
ret = m_pDD->CreateSurface( &ddsd, &m_pddsBackBuffer, NULL );
if (ret) { LOGFAIL(); goto fail; }
// clipper
ret = m_pDD->CreateClipper( 0, &pcClipper, NULL );
if (ret) { LOGFAIL(); goto fail; }
ret = pcClipper->SetHWnd( 0, FrameWnd );
if (ret) { LOGFAIL(); goto fail; }
ret = m_pddsFrontBuffer->SetClipper( pcClipper );
if (ret) { LOGFAIL(); goto fail; }
RELEASE(pcClipper);
return 0;
fail:
RELEASE(pcClipper);
DirectExitDDraw();
return 1;
}
static int DirectScreenDDraw()
{
DDSURFACEDESC2 sd;
unsigned short *ps=EmuScreen;
int ret, x, y;
memset(&sd, 0, sizeof(sd));
sd.dwSize = sizeof(sd);
ret = m_pddsBackBuffer->Lock(NULL, &sd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_WRITEONLY, NULL);
if (ret) { LOGFAIL(); return 1; }
//lprintf("w: %i h: %i pi: %i pf: %i\n", sd.dwWidth, sd.dwHeight, sd.lPitch, sd.ddpfPixelFormat.dwRGBBitCount);
if (sd.ddpfPixelFormat.dwRGBBitCount == 32)
{
int *dst = (int *)sd.lpSurface;
for (y = 0; y < EmuHeight; y++)
{
for (x = 0; x < EmuWidth; x++)
{
int s = *ps++;
dst[x] = ((s&0xf800)<<8) | ((s&0x07e0)<<5) | ((s&0x001f)<<3);
}
dst = (int *)((char *)dst + sd.lPitch);
}
}
else if (sd.ddpfPixelFormat.dwRGBBitCount == 24) /* wine uses this for me */
{
void *dst = sd.lpSurface;
for (y = 0; y < EmuHeight; y++)
{
unsigned char *dst1 = (unsigned char *) dst;
for (x = 0; x < EmuWidth; x++, dst1 += 3)
{
int s = *ps++;
dst1[2] = (s&0xf800)>>8; dst1[1] = (s&0x07e0)>>3; dst1[0] = s<<3; // BGR
}
dst = (void *)((char *)dst + sd.lPitch);
}
}
else if (sd.ddpfPixelFormat.dwRGBBitCount == 16)
{
unsigned short *dst = (unsigned short *)sd.lpSurface;
for (y = 0; y < EmuHeight; y++)
{
memcpy(dst, ps, EmuWidth*2);
ps += EmuWidth;
dst = (unsigned short *)((char *)dst + sd.lPitch);
}
}
else
{
LOGFAIL();
}
ret = m_pddsBackBuffer->Unlock(NULL);
if (ret) { LOGFAIL(); return 1; }
return 0;
}
static int DirectClearDDraw(unsigned int colour)
{
int ret;
DDBLTFX ddbltfx;
ZeroMemory( &ddbltfx, sizeof(ddbltfx) );
ddbltfx.dwSize = sizeof(ddbltfx);
ddbltfx.dwFillColor = colour;
if (m_pddsBackBuffer != NULL)
ret = m_pddsBackBuffer->Blt( NULL, NULL, NULL, DDBLT_COLORFILL, &ddbltfx );
if (ret) { LOGFAIL(); return 1; }
return 0;
}
static int DirectPresentDDraw()
{
int ret = 0;
if (FrameRectMy.right - FrameRectMy.left > 0 && FrameRectMy.bottom - FrameRectMy.top > 0)
ret = m_pddsFrontBuffer->Blt(&FrameRectMy, m_pddsBackBuffer, &EmuScreenRect, DDBLT_WAIT, NULL);
if (ret) { LOGFAIL(); return 1; }
return 0;
}
/* D3D */
int DirectInit()
{
#if USE_D3D
D3DPRESENT_PARAMETERS d3dpp;
D3DDISPLAYMODE mode;
int i,u,ret=0;
memset(&d3dpp,0,sizeof(d3dpp));
memset(&mode,0,sizeof(mode));
Direct3D=Direct3DCreate8(D3D_SDK_VERSION); if (Direct3D==NULL) return 1;
// Set up the structure used to create the D3D device:
d3dpp.BackBufferWidth =MainWidth;
d3dpp.BackBufferHeight=MainHeight;
d3dpp.BackBufferCount =1;
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dpp.MultiSampleType =D3DMULTISAMPLE_NONE;
#ifdef _XBOX
d3dpp.BackBufferFormat=D3DFMT_X8R8G8B8;
d3dpp.FullScreen_RefreshRateInHz=60;
#else
Direct3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&mode);
d3dpp.BackBufferFormat=mode.Format;
d3dpp.Windowed=1;
d3dpp.hDeviceWindow=FrameWnd;
#endif
// Try to create a device with hardware vertex processing:
for (i=0;i<3;i++)
{
int behave=D3DCREATE_HARDWARE_VERTEXPROCESSING;
// Try software vertex processing:
if (i==1) behave=D3DCREATE_MIXED_VERTEXPROCESSING;
if (i==2) behave=D3DCREATE_SOFTWARE_VERTEXPROCESSING;
Direct3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,FrameWnd,
behave|D3DCREATE_MULTITHREADED,&d3dpp,&Device);
if (Device) break;
}
if (Device==NULL)
{
#if 0
// try ref
Direct3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_REF,FrameWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_MULTITHREADED,&d3dpp,&Device);
if (Device==NULL) goto fail0;
HMODULE test = LoadLibrary("d3d8d.dll");
if (test != NULL) FreeLibrary(test);
else {
error("Sorry, but this program requires Direct3D with hardware acceleration.\n\n"
"You can try using Direct3D software emulation, but you have to install "
"DirectX SDK for it to work\n(it seems to be missing now).");
goto fail1;
}
#else
goto fail1;
#endif
}
Device->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&DirectBack);
if (DirectBack==NULL) goto fail1;
Device->CreateVertexBuffer(sizeof(VertexList),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,&VertexBuffer);
if (VertexBuffer==NULL) goto fail2;
ret=TexScreenInit(); if (ret) goto fail3;
//FontInit();
Device->SetRenderState(D3DRS_LIGHTING,0); // Turn off lighting
// Set up texture modes:
Device->SetTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_CLAMP);
Device->SetTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_CLAMP);
return 0;
fail3:
RELEASE(VertexBuffer)
fail2:
RELEASE(DirectBack)
fail1:
RELEASE(Device)
fail0:
RELEASE(Direct3D)
// error("Failed to use Direct3D, trying DirectDraw..");
#endif
// try DirectDraw
return DirectDrawInit();
}
void DirectExit()
{
#ifdef USE_D3D
TexScreenExit();
// d3d
RELEASE(VertexBuffer)
RELEASE(DirectBack)
RELEASE(Device)
RELEASE(Direct3D)
#endif
DirectExitDDraw();
}
int DirectClear(unsigned int colour)
{
#ifdef USE_D3D
if (Device != NULL) {
Device->Clear(0,NULL,D3DCLEAR_TARGET,colour,1.0f,0);
return 0;
}
#endif
return DirectClearDDraw(colour);
}
int DirectPresent()
{
#ifdef USE_D3D
if (Device != NULL) {
Device->Present(NULL,NULL,NULL,NULL);
return 0;
}
#endif
return DirectPresentDDraw();
}
#ifdef USE_D3D
#define PI 3.14159265f
static int MakeVertexList()
{
struct CustomVertex *vert=NULL,*pv=NULL;
float dist=0.0f;
float scalex=0.0f,scaley=0.0f;
unsigned int colour=0xffffff;
float right=0.0f,bottom=0.0f;
if (LoopMode!=8) colour=0x102040;
dist=10.0f; scalex=dist*1.3333f; scaley=dist;
scalex*=640.0f/(float)MainWidth;
scaley*=448.0f/(float)MainHeight;
vert=VertexList;
// Put the vertices for the corners of the screen:
pv=vert;
pv->z=dist;
pv->x=-scalex; pv->y=scaley;
pv->colour=colour; pv++;
*pv=vert[0]; pv->x= scalex; pv->y= scaley; pv++;
*pv=vert[0]; pv->x=-scalex; pv->y=-scaley; pv++;
*pv=vert[0]; pv->x= scalex; pv->y=-scaley; pv++;
// Find where the screen images ends on the texture
right =(float)EmuWidth /(float)TexWidth;
bottom=(float)EmuHeight/(float)TexHeight;
// Write texture coordinates:
pv=vert;
pv->u=0.0f; pv->v=0.00f; pv++;
pv->u=right; pv->v=0.00f; pv++;
pv->u=0.0f; pv->v=bottom; pv++;
pv->u=right; pv->v=bottom; pv++;
return 0;
}
static int SetupMatrices()
{
D3DXVECTOR3 eye ( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 look( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 up ( 0.0f, 1.0f, 0.0f );
D3DXMATRIX mat;
float nudgex=0.0f,nudgey=0.0f;
memset(&mat,0,sizeof(mat));
mat.m[0][0]=mat.m[1][1]=mat.m[2][2]=mat.m[3][3]=1.0f;
Device->SetTransform(D3DTS_WORLD,&mat);
look.x=(float)Inp.axis[2]/2457.6f;
look.y=(float)Inp.axis[3]/2457.6f;
look.z=10.0f;
// Nudge pixels to the centre of each screen pixel:
nudgex=13.3333f/(float)(MainWidth <<1);
nudgey=10.0000f/(float)(MainHeight<<1);
eye.x +=nudgex; eye.y +=nudgey;
look.x+=nudgex; look.y+=nudgey;
D3DXMatrixLookAtLH(&mat,&eye,&look,&up);
Device->SetTransform(D3DTS_VIEW,&mat);
D3DXMatrixPerspectiveFovLH(&mat, 0.5f*PI, 1.3333f, 0.2f, 1000.0f);
Device->SetTransform(D3DTS_PROJECTION,&mat);
return 0;
}
int DirectScreen()
{
unsigned char *lock=NULL;
int ret;
if (Device == NULL)
return DirectScreenDDraw();
// Copy the screen to the screen texture:
#ifdef _XBOX
TexScreenSwizzle();
#else
ret=TexScreenLinear();
if (ret) lprintf("TexScreenLinear failed\n");
#endif
SetupMatrices();
MakeVertexList();
// Copy vertices in:
VertexBuffer->Lock(0,sizeof(VertexList),&lock,0);
if (lock==NULL) { lprintf("VertexBuffer->Lock failed\n"); return 1; }
memcpy(lock,VertexList,sizeof(VertexList));
VertexBuffer->Unlock();
Device->BeginScene();
Device->SetTexture(0,TexScreen);
Device->SetStreamSource(0,VertexBuffer,sizeof(CustomVertex));
Device->SetVertexShader(D3DFVF_CUSTOMVERTEX);
Device->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
Device->EndScene();
return 0;
}
#else
int DirectScreen()
{
return DirectScreenDDraw();
}
#endif

View file

@ -1,84 +0,0 @@
#include "app.h"
unsigned short *EmuScreen=NULL;
int EmuWidth=320,EmuHeight=224;
RECT EmuScreenRect = { 0, 0, 320, 224 };
int PicoPadAdd = 0;
static int EmuScan(unsigned int num);
unsigned char *PicoDraw2FB = NULL;
int EmuInit()
{
int len=0;
PicoInit();
// Allocate screen:
EmuWidth=320; EmuHeight=224;
len=EmuWidth*EmuHeight; len<<=1;
EmuScreen=(unsigned short *)malloc(len); if (EmuScreen==NULL) return 1;
PicoDraw2FB=(unsigned char *)malloc((8+320)*(8+224+8)*2);
memset(EmuScreen,0,len);
PicoDrawSetColorFormat(1);
PicoScanBegin=EmuScan;
return 0;
}
void EmuExit()
{
//RomFree();
free(EmuScreen); EmuScreen=NULL; // Deallocate screen
free(PicoDraw2FB);
EmuWidth=EmuHeight=0;
PicoExit();
}
// Megadrive scanline callback:
static int EmuScan(unsigned int num)
{
DrawLineDest=EmuScreen+(num<<8)+(num<<6);
return 0;
}
int EmuFrame()
{
char map[12]={0,1,2,3,8,9,10,4,11,12,13,14}; // Joypads, format is UDLR BCAS ZYXM
int a=0,input=0;
// Set Megadrive buttons:
for (a=0;a<12;a++)
{
int m=map[a];
if (m>=0) if (Inp.button[m]>30) input|=1<<a;
}
PicoPad[0]=input;
PicoPad[0]|=PicoPadAdd;
PsndOut=(short *)DSoundNext;
PicoFrame();
PsndOut=NULL;
return 0;
}
void mp3_update(int *buffer, int length, int stereo)
{
}
void mp3_start_play(FILE *f, int pos)
{
}
int mp3_get_bitrate(FILE *f, int size)
{
return -1;
}

View file

@ -1,193 +0,0 @@
#include "app.h"
#include <commdlg.h>
struct Input Inp;
// --------------------- XBox Input -----------------------------
#ifdef _XBOX
static HANDLE GamePad=NULL;
static XINPUT_STATE Pad;
static int DeadZone(short *paxis)
{
int zone=0x2000;
int a=*paxis;
if (a<-zone) a+=zone;
else if (a> zone) a-=zone; else a=0;
*paxis=(short)a;
return 0;
}
static int DeviceRead()
{
int but=0,a=0;
memset(Inp.axis, 0,sizeof(Inp.axis));
memset(Inp.button,0,sizeof(Inp.button));
if (GamePad==NULL) GamePad=XInputOpen(XDEVICE_TYPE_GAMEPAD,0,XDEVICE_NO_SLOT,NULL);
if (GamePad==NULL) return 1;
// Read XBox joypad:
XInputGetState(GamePad,&Pad);
// Get analog axes:
Inp.axis[0]=Pad.Gamepad.sThumbLX;
Inp.axis[1]=Pad.Gamepad.sThumbLY;
Inp.axis[2]=Pad.Gamepad.sThumbRX;
Inp.axis[3]=Pad.Gamepad.sThumbRY;
for (a=0;a<4;a++) DeadZone(Inp.axis+a);
// Get digital buttons:
but=Pad.Gamepad.wButtons;
for (a=0;a<8;a++)
{
if (but&(1<<a)) Inp.button[a]=0xff;
}
// Get analog buttons:
memcpy(Inp.button+8, Pad.Gamepad.bAnalogButtons, 8);
return 0;
}
#endif
// --------------------- Windows Input -----------------------------
#ifndef _XBOX
static int DeviceRead()
{
int push=0x6000;
int axis[]={0,0,0,0};
int i=0;
memset(Inp.axis, 0,sizeof(Inp.axis));
memset(Inp.button,0,sizeof(Inp.button));
if (GetForegroundWindow()!=FrameWnd) return 1;
if (GetAsyncKeyState(VK_LEFT )) axis[0]-=push;
if (GetAsyncKeyState(VK_RIGHT)) axis[0]+=push;
if (GetAsyncKeyState(VK_DOWN )) axis[1]-=push;
if (GetAsyncKeyState(VK_UP )) axis[1]+=push;
for (i=0;i<4;i++) Inp.axis[i]=(short)axis[i];
if (GetAsyncKeyState(VK_RETURN)) Inp.button[4]=0xff; // Start
//if (GetAsyncKeyState(VK_ESCAPE)) Inp.button[7]=0xff; // Right thumb
if (GetAsyncKeyState('Z')) Inp.button[10]=0xff;
if (GetAsyncKeyState('X')) Inp.button[ 8]=0xff;
if (GetAsyncKeyState('C')) Inp.button[ 9]=0xff;
if (GetAsyncKeyState('A')) Inp.button[13]=0xff;
if (GetAsyncKeyState('S')) Inp.button[12]=0xff;
if (GetAsyncKeyState('D')) Inp.button[11]=0xff;
if (GetAsyncKeyState('F')) Inp.button[14]=0xff;
static int sblobked = 0;
if (!sblobked && GetAsyncKeyState(VK_TAB)) {
PicoReset();
sblobked = 1;
}
else if (!sblobked && GetAsyncKeyState(VK_ESCAPE))
{
PostMessage(FrameWnd, WM_COMMAND, 0x20000 | 1000, 0);
sblobked = 1;
}
else
sblobked = GetAsyncKeyState(VK_TAB) | GetAsyncKeyState(VK_ESCAPE);
return 0;
}
#endif
int InputInit()
{
memset(&Inp,0,sizeof(Inp));
#ifdef _XBOX
memset(&Pad,0,sizeof(Pad));
XInitDevices(0,NULL);
#endif
return 0;
}
void InputExit()
{
#ifdef _XBOX
if (GamePad) XInputClose(GamePad);
GamePad=NULL;
#endif
}
int InputUpdate()
{
int i=0;
int push=0x2000;
DeviceRead(); // Read XBox or PC device
// Use left analog for left digital too:
if (Inp.axis[1]>= push) Inp.button[0]|=0xff; // Up
if (Inp.axis[1]<=-push) Inp.button[1]|=0xff; // Down
if (Inp.axis[0]<=-push) Inp.button[2]|=0xff; // Left
if (Inp.axis[0]>= push) Inp.button[3]|=0xff; // Right
// Update debounce/time held information:
for (i=0;i<sizeof(Inp.held);i++)
{
if (Inp.held[i]==0)
{
if (Inp.button[i]>30) Inp.held[i]=1; // Just pressed
}
else
{
// Is the button still being held down?
Inp.held[i]++;
if (Inp.held[i]>=0x80) Inp.held[i]&=0xbf; // (Keep looping around)
if (Inp.button[i]<25) Inp.held[i]=0; // No
}
}
// Work out some key repeat values:
for (i=0;i<sizeof(Inp.repeat);i++)
{
char rep=0;
int held=Inp.held[i];
if (held==1) rep=1;
if (held>=0x20 && (held&1)) rep=1;
Inp.repeat[i]=rep;
}
return 0;
}
// Set Lightgun calibration values:
int InputLightCal(int cx,int cy,int ux,int uy)
{
#ifdef _XBOX
XINPUT_LIGHTGUN_CALIBRATION_OFFSETS cal;
memset(&cal,0,sizeof(cal));
cal.wCenterX =(WORD)cx;
cal.wCenterY =(WORD)cy;
cal.wUpperLeftX=(WORD)ux;
cal.wUpperLeftY=(WORD)uy;
XInputSetLightgunCalibration(GamePad,&cal);
#endif
(void)(cx+cy+ux+uy);
return 0;
}

View file

@ -1,143 +0,0 @@
#include "app.h"
//#include "FileMenu.h"
char LoopQuit=0,LoopWait=0,LoopWaiting=0;
static FILE *DebugFile=NULL;
int LoopMode=0;
static void UpdateSound(int len);
int LoopInit()
{
int ret=0;
// bits LSb->MSb:
// enable_ym2612&dac, enable_sn76496, enable_z80, stereo_sound;
// alt_renderer, 6button_gamepad, accurate_timing, accurate_sprites
PicoOpt=0xbccf;
PsndRate=44100;
// Init Direct3D:
ret=DirectInit(); if (ret) { error("DirectX video init failed"); return 1; }
InputInit();
// Init DirectSound:
//DSoundInit();
ret=EmuInit(); if (ret) return 1;
LoopMode=8;
PicoWriteSound = UpdateSound;
PicoAutoRgnOrder = 0x184;
return 0;
}
extern "C" char *debugString();
void LoopExit()
{
dprintf(debugString());
EmuExit();
InputExit();
DirectExit();
if (DebugFile) fclose(DebugFile);
DebugFile=NULL;
}
// ----------------------------------------------------------------
static void UpdateSound(int len)
{
while (DSoundUpdate() > 0) { Sleep(1); }
//while (DSoundUpdate()== 0) { }
}
static void PostProcess()
{
static int lock_to_1_1_prev = 0, is_40_prev = -1;
int is_40;
PicoGetInternal(PI_IS40_CELL, (pint_ret_t *)&is_40);
if (lock_to_1_1)
{
if (is_40 != is_40_prev || !lock_to_1_1_prev)
PostMessage(FrameWnd, WM_COMMAND, 0x20000 | (is_40 ? 1100 : 1101), 0);
}
if (is_40 != is_40_prev)
{
EmuScreenRect.left = is_40 ? 0 : 32;
EmuScreenRect.right = is_40 ? 320 : 256+32;
}
lock_to_1_1_prev = lock_to_1_1;
is_40_prev = is_40;
}
int LoopCode()
{
// Main loop:
while (!LoopQuit)
{
if (LoopWait)
{
DSoundExit();
while (!LoopQuit && LoopWait) { LoopWaiting=1; Sleep(100); }
if (LoopQuit) break;
DSoundInit();
}
InputUpdate();
DirectClear(0);
EmuFrame();
PostProcess();
DirectScreen();
DirectPresent();
// UpdateSound();
}
DSoundExit();
return 0;
}
// -------------------------------------------------------------------------------------
#if 0
extern "C" int dprintf(char *format, ...)
{
char *name=NULL;
va_list val=NULL;
#ifdef _XBOX
name="d:\\zout.txt";
#else
name="zout.txt";
#endif
if (DebugFile==NULL) DebugFile=fopen(name,"wt");
if (DebugFile==NULL) return 1;
fprintf(DebugFile, "%05i: ", emu_frame);
va_start(val,format);
vfprintf(DebugFile,format,val);
fprintf(DebugFile, "\n");
fflush(DebugFile);
va_end(val);
return 0;
}
#endif
extern "C" int lprintf(char *format, ...)
{
char str[512];
va_list val=NULL;
va_start(val,format);
vsprintf(str,format,val);
va_end(val);
OutputDebugString(str);
return 0;
}

View file

@ -1,576 +0,0 @@
#include "app.h"
#include "version.h"
#include <crtdbg.h>
#include <commdlg.h>
#include "../../common/readpng.h"
#include "../../common/config.h"
char *romname=NULL;
HWND FrameWnd=NULL;
RECT FrameRectMy;
int lock_to_1_1 = 1;
static HWND PicoSwWnd=NULL, PicoPadWnd=NULL;
int MainWidth=720,MainHeight=480;
static HMENU mmain = 0, mdisplay = 0, mpicohw = 0;
static int rom_loaded = 0;
static HBITMAP ppad_bmp = 0;
static HBITMAP ppage_bmps[7] = { 0, };
static char rom_name[0x20*3+1];
static int main_wnd_as_pad = 0;
static void UpdateRect()
{
WINDOWINFO wi;
memset(&wi, 0, sizeof(wi));
wi.cbSize = sizeof(wi);
GetWindowInfo(FrameWnd, &wi);
FrameRectMy = wi.rcClient;
}
static int extract_rom_name(char *dest, const unsigned char *src, int len)
{
char *p = dest, s_old = 0x20;
int i;
for (i = len - 1; i >= 0; i--)
{
if (src[i^1] != ' ') break;
}
len = i + 1;
for (i = 0; i < len; i++)
{
unsigned char s = src[i^1];
if (s == 0x20 && s_old == 0x20) continue;
else if (s >= 0x20 && s < 0x7f && s != '%')
{
*p++ = s;
}
else
{
sprintf(p, "%%%02x", s);
p += 3;
}
s_old = s;
}
*p = 0;
return p - dest;
}
static void check_name_alias(const char *afname)
{
char buff[256], *var, *val;
FILE *f;
int ret;
f = fopen(afname, "r");
if (f == NULL) return;
while (1)
{
ret = config_get_var_val(f, buff, sizeof(buff), &var, &val);
if (ret == 0) break;
if (ret == -1) continue;
if (strcmp(rom_name, var) == 0) {
lprintf("rom aliased: \"%s\" -> \"%s\"\n", rom_name, val);
strncpy(rom_name, val, sizeof(rom_name));
break;
}
}
fclose(f);
}
static HBITMAP png2hb(const char *fname, int is_480)
{
BITMAPINFOHEADER bih;
HBITMAP bmp;
void *bmem;
int ret;
bmem = calloc(1, is_480 ? 480*240*3 : 320*240*3);
if (bmem == NULL) return NULL;
ret = readpng(bmem, fname, is_480 ? READPNG_480_24 : READPNG_320_24);
if (ret != 0) {
free(bmem);
return NULL;
}
memset(&bih, 0, sizeof(bih));
bih.biSize = sizeof(bih);
bih.biWidth = is_480 ? 480 : 320;
bih.biHeight = -240;
bih.biPlanes = 1;
bih.biBitCount = 24;
bih.biCompression = BI_RGB;
bmp = CreateDIBitmap(GetDC(FrameWnd), &bih, CBM_INIT, bmem, (BITMAPINFO *)&bih, 0);
if (bmp == NULL)
lprintf("CreateDIBitmap failed with %i", GetLastError());
free(bmem);
return bmp;
}
static void PrepareForROM(void)
{
unsigned char *rom_data = NULL;
int i, ret, show = PicoAHW & PAHW_PICO;
PicoGetInternal(PI_ROM, (pint_ret_t *) &rom_data);
EnableMenuItem(mmain, 2, MF_BYPOSITION|(show ? MF_ENABLED : MF_GRAYED));
ShowWindow(PicoPadWnd, show ? SW_SHOWNA : SW_HIDE);
ShowWindow(PicoSwWnd, show ? SW_SHOWNA : SW_HIDE);
CheckMenuItem(mpicohw, 1210, show ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(mpicohw, 1211, show ? MF_CHECKED : MF_UNCHECKED);
PostMessage(FrameWnd, WM_COMMAND, 1220 + PicoPicohw.page, 0);
DrawMenuBar(FrameWnd);
InvalidateRect(PicoSwWnd, NULL, 1);
PicoPicohw.pen_pos[0] =
PicoPicohw.pen_pos[1] = 0x8000;
PicoPadAdd = 0;
ret = extract_rom_name(rom_name, rom_data + 0x150, 0x20);
if (ret == 0)
extract_rom_name(rom_name, rom_data + 0x130, 0x20);
if (show)
{
char path[MAX_PATH], *p;
GetModuleFileName(NULL, path, sizeof(path) - 32);
p = strrchr(path, '\\');
if (p == NULL) p = path;
else p++;
if (ppad_bmp == NULL) {
strcpy(p, "pico\\pad.png");
ppad_bmp = png2hb(path, 0);
}
strcpy(p, "pico\\alias.txt");
check_name_alias(path);
for (i = 0; i < 7; i++) {
if (ppage_bmps[i] != NULL) DeleteObject(ppage_bmps[i]);
sprintf(p, "pico\\%s_%i.png", rom_name, i);
ppage_bmps[i] = png2hb(path, 1);
}
// games usually don't have page 6, so just duplicate page 5.
if (ppage_bmps[6] == NULL && ppage_bmps[5] != NULL) {
sprintf(p, "pico\\%s_5.png", rom_name);
ppage_bmps[6] = png2hb(path, 1);
}
}
}
static void LoadROM(const char *cmdpath)
{
static char rompath[MAX_PATH] = { 0, };
unsigned char *rom_data_new = NULL;
unsigned int rom_size = 0;
pm_file *rom = NULL;
int oldwait=LoopWait;
int i, ret;
if (cmdpath) {
strcpy(rompath, cmdpath + (cmdpath[0] == '\"' ? 1 : 0));
if (rompath[strlen(rompath)-1] == '\"') rompath[strlen(rompath)-1] = 0;
if (strlen(rompath) > 4) rom = pm_open(rompath);
}
if (!rom) {
OPENFILENAME of; ZeroMemory(&of, sizeof(OPENFILENAME));
of.lStructSize = sizeof(OPENFILENAME);
of.lpstrFilter = "ROMs\0*.smd;*.bin;*.gen;*.zip\0";
of.lpstrFile = rompath; rompath[0] = 0;
of.nMaxFile = MAX_PATH;
of.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
of.hwndOwner = FrameWnd;
if (!GetOpenFileName(&of)) return;
rom = pm_open(rompath);
if (!rom) { error("failed to open ROM"); return; }
}
ret=PicoCartLoad(rom, &rom_data_new, &rom_size);
pm_close(rom);
if (ret) {
error("failed to load ROM");
return;
}
// halt the work thread..
// just a hack, should've used proper sync. primitives here, but who will use this emu anyway..
LoopWaiting=0;
LoopWait=1;
for (i = 0; LoopWaiting == 0 && i < 10; i++) Sleep(100);
PicoCartUnload();
PicoCartInsert(rom_data_new, rom_size);
PrepareForROM();
rom_loaded = 1;
romname = rompath;
LoopWait=0;
}
static int rect_widths[4] = { 320, 256, 640, 512 };
static int rect_heights[4] = { 224, 224, 448, 448 };
// Window proc for the frame window:
static LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
POINT pt;
RECT rc;
int i;
switch (msg)
{
case WM_CLOSE: PostQuitMessage(0); return 0;
case WM_DESTROY: FrameWnd=NULL; break; // Blank handle
case WM_SIZE:
case WM_MOVE:
case WM_SIZING: UpdateRect(); break;
case WM_COMMAND:
switch (LOWORD(wparam))
{
case 1000: LoadROM(NULL); break;
case 1001: PicoReset(); return 0;
case 1002: PostQuitMessage(0); return 0;
case 1100:
case 1101:
case 1102:
case 1103:
LoopWait=1; // another sync hack
for (i = 0; !LoopWaiting && i < 10; i++) Sleep(10);
FrameRectMy.right = FrameRectMy.left + rect_widths[wparam&3];
FrameRectMy.bottom = FrameRectMy.top + rect_heights[wparam&3];
AdjustWindowRect(&FrameRectMy, WS_OVERLAPPEDWINDOW, 1);
MoveWindow(hwnd, FrameRectMy.left, FrameRectMy.top,
FrameRectMy.right-FrameRectMy.left, FrameRectMy.bottom-FrameRectMy.top, 1);
UpdateRect();
if (HIWORD(wparam) == 0) { // locally sent
lock_to_1_1=0;
CheckMenuItem(mdisplay, 1104, MF_UNCHECKED);
}
if (rom_loaded) LoopWait=0;
return 0;
case 1104:
lock_to_1_1=!lock_to_1_1;
CheckMenuItem(mdisplay, 1104, lock_to_1_1 ? MF_CHECKED : MF_UNCHECKED);
return 0;
case 1210:
case 1211:
i = IsWindowVisible((LOWORD(wparam)&1) ? PicoPadWnd : PicoSwWnd);
i = !i;
ShowWindow((LOWORD(wparam)&1) ? PicoPadWnd : PicoSwWnd, i ? SW_SHOWNA : SW_HIDE);
CheckMenuItem(mpicohw, LOWORD(wparam), i ? MF_CHECKED : MF_UNCHECKED);
return 0;
case 1212:
main_wnd_as_pad = !main_wnd_as_pad;
CheckMenuItem(mpicohw, 1212, main_wnd_as_pad ? MF_CHECKED : MF_UNCHECKED);
return 0;
case 1220:
case 1221:
case 1222:
case 1223:
case 1224:
case 1225:
case 1226:
PicoPicohw.page = LOWORD(wparam) % 10;
for (i = 0; i < 7; i++)
CheckMenuItem(mpicohw, 1220 + i, MF_UNCHECKED);
CheckMenuItem(mpicohw, 1220 + PicoPicohw.page, MF_CHECKED);
InvalidateRect(PicoSwWnd, NULL, 1);
return 0;
case 1300:
MessageBox(FrameWnd, "PicoDrive v" VERSION " (c) notaz, 2006-2008\n"
"SVP and Pico demo edition\n\n"
"Credits:\n"
"fDave: base code of PicoDrive, GenaDrive (the frontend)\n"
"Chui: Fame/C\n"
"NJ: CZ80\n"
"MAME devs: YM2612 and SN76496 cores\n"
"Stéphane Dallongeville: Gens code, base of Fame/C (C68K), CZ80\n"
"Tasco Deluxe: SVP RE work\n"
"Pierpaolo Prazzoli: info about SSP16 chips\n",
"About", 0);
return 0;
}
break;
case WM_TIMER:
GetCursorPos(&pt);
GetWindowRect(PicoSwWnd, &rc);
if (PtInRect(&rc, pt)) break;
GetWindowRect(PicoPadWnd, &rc);
if (PtInRect(&rc, pt)) break;
PicoPicohw.pen_pos[0] |= 0x8000;
PicoPicohw.pen_pos[1] |= 0x8000;
PicoPadAdd = 0;
break;
case WM_LBUTTONDOWN: PicoPadAdd |= 0x20; return 0;
case WM_LBUTTONUP: PicoPadAdd &= ~0x20; return 0;
case WM_MOUSEMOVE:
if (!main_wnd_as_pad) break;
PicoPicohw.pen_pos[0] = 0x03c + (320 * LOWORD(lparam) / (FrameRectMy.right - FrameRectMy.left));
PicoPicohw.pen_pos[1] = 0x1fc + (232 * HIWORD(lparam) / (FrameRectMy.bottom - FrameRectMy.top));
SetTimer(FrameWnd, 100, 1000, NULL);
break;
}
return DefWindowProc(hwnd,msg,wparam,lparam);
}
static void key_down(WPARAM key)
{
switch (key) {
case VK_LEFT: PicoPadAdd |= 4; break;
case VK_RIGHT: PicoPadAdd |= 8; break;
case VK_UP: PicoPadAdd |= 1; break;
case VK_DOWN: PicoPadAdd |= 2; break;
case 'X': PicoPadAdd |= 0x10; break;
}
}
static void key_up(WPARAM key)
{
switch (key) {
case VK_LEFT: PicoPadAdd &= ~0x04; break;
case VK_RIGHT: PicoPadAdd &= ~0x08; break;
case VK_UP: PicoPadAdd &= ~0x01; break;
case VK_DOWN: PicoPadAdd &= ~0x02; break;
case 'X': PicoPadAdd &= ~0x10; break;
}
}
static LRESULT CALLBACK PicoSwWndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
PAINTSTRUCT ps;
HDC hdc, hdc2;
switch (msg)
{
case WM_DESTROY: PicoSwWnd=NULL; break;
case WM_LBUTTONDOWN: PicoPadAdd |= 0x20; return 0;
case WM_LBUTTONUP: PicoPadAdd &= ~0x20; return 0;
case WM_MOUSEMOVE:
if (HIWORD(lparam) < 0x20) break;
PicoPicohw.pen_pos[0] = 0x03c + LOWORD(lparam) * 2/3;
PicoPicohw.pen_pos[1] = 0x2f8 + HIWORD(lparam) - 0x20;
SetTimer(FrameWnd, 100, 1000, NULL);
break;
case WM_KEYDOWN: key_down(wparam); break;
case WM_KEYUP: key_up(wparam); break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
if (ppage_bmps[PicoPicohw.page] == NULL)
{
SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
SetTextColor(hdc, RGB(255, 255, 255));
SetBkColor(hdc, RGB(0, 0, 0));
TextOut(hdc, 2, 2, "missing PNGs for", 16);
TextOut(hdc, 2, 18, rom_name, strlen(rom_name));
}
else
{
hdc2 = CreateCompatibleDC(GetDC(FrameWnd));
SelectObject(hdc2, ppage_bmps[PicoPicohw.page]);
BitBlt(hdc, 0, 0, 480, 240, hdc2, 0, 0, SRCCOPY);
DeleteDC(hdc2);
}
EndPaint(hwnd, &ps);
return 0;
}
return DefWindowProc(hwnd,msg,wparam,lparam);
}
static LRESULT CALLBACK PicoPadWndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
PAINTSTRUCT ps;
HDC hdc, hdc2;
switch (msg)
{
case WM_DESTROY: PicoPadWnd=NULL; break;
case WM_LBUTTONDOWN: PicoPadAdd |= 0x20; return 0;
case WM_LBUTTONUP: PicoPadAdd &= ~0x20; return 0;
case WM_MOUSEMOVE:
PicoPicohw.pen_pos[0] = 0x03c + LOWORD(lparam);
PicoPicohw.pen_pos[1] = 0x1fc + HIWORD(lparam);
SetTimer(FrameWnd, 100, 1000, NULL);
break;
case WM_KEYDOWN: key_down(wparam); break;
case WM_KEYUP: key_up(wparam); break;
case WM_PAINT:
if (ppad_bmp == NULL) break;
hdc = BeginPaint(hwnd, &ps);
hdc2 = CreateCompatibleDC(GetDC(FrameWnd));
SelectObject(hdc2, ppad_bmp);
BitBlt(hdc, 0, 0, 320, 240, hdc2, 0, 0, SRCCOPY);
EndPaint(hwnd, &ps);
DeleteDC(hdc2);
return 0;
}
return DefWindowProc(hwnd,msg,wparam,lparam);
}
static int FrameInit()
{
WNDCLASS wc;
RECT rect={0,0,0,0};
HMENU mfile;
int style=0;
int left=0,top=0,width=0,height=0;
memset(&wc,0,sizeof(wc));
// Register the window class:
wc.lpfnWndProc=WndProc;
wc.hInstance=GetModuleHandle(NULL);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground=CreateSolidBrush(0);
wc.lpszClassName="PicoMainFrame";
RegisterClass(&wc);
wc.lpszClassName="PicoSwWnd";
wc.lpfnWndProc=PicoSwWndProc;
RegisterClass(&wc);
wc.lpszClassName="PicoPadWnd";
wc.lpfnWndProc=PicoPadWndProc;
RegisterClass(&wc);
rect.right =320;//MainWidth;
rect.bottom=224;//MainHeight;
// Adjust size of windows based on borders:
style=WS_OVERLAPPEDWINDOW;
AdjustWindowRect(&rect,style,1);
width =rect.right-rect.left;
height=rect.bottom-rect.top;
// Place window in the centre of the screen:
SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0);
left=rect.left+rect.right;
top=rect.top+rect.bottom;
left-=width; left>>=1;
top-=height; top>>=1;
// Create menu:
mfile = CreateMenu();
InsertMenu(mfile, -1, MF_BYPOSITION|MF_STRING, 1000, "&Load ROM");
InsertMenu(mfile, -1, MF_BYPOSITION|MF_STRING, 1001, "&Reset");
InsertMenu(mfile, -1, MF_BYPOSITION|MF_STRING, 1002, "E&xit");
mdisplay = CreateMenu();
InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1100, "320x224");
InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1101, "256x224");
InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1102, "640x448");
InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1103, "512x448");
InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1104, "Lock to 1:1");
mpicohw = CreateMenu();
InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1210, "Show &Storyware");
InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1211, "Show &Drawing pad");
InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1212, "&Main window as pad");
InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_SEPARATOR, 0, NULL);
InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1220, "Title page (&0)");
InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1221, "Page &1");
InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1222, "Page &2");
InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1223, "Page &3");
InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1224, "Page &4");
InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1225, "Page &5");
InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1226, "Page &6");
mmain = CreateMenu();
InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING|MF_POPUP, (UINT_PTR) mfile, "&File");
InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING|MF_POPUP, (UINT_PTR) mdisplay, "&Display");
InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING|MF_POPUP, (UINT_PTR) mpicohw, "&Pico");
EnableMenuItem(mmain, 2, MF_BYPOSITION|MF_GRAYED);
// InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING|MF_POPUP, 1200, "&Config");
InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING, 1300, "&About");
// Create the window:
FrameWnd=CreateWindow("PicoMainFrame","PicoDrive " VERSION,style|WS_VISIBLE,
left,top,width,height,NULL,mmain,NULL,NULL);
CheckMenuItem(mdisplay, 1104, lock_to_1_1 ? MF_CHECKED : MF_UNCHECKED);
ShowWindow(FrameWnd, SW_NORMAL);
UpdateWindow(FrameWnd);
UpdateRect();
// create Pico windows
style = WS_OVERLAPPED|WS_CAPTION|WS_BORDER;
rect.left=rect.top=0;
rect.right =320;
rect.bottom=224;
AdjustWindowRect(&rect,style,1);
width =rect.right-rect.left;
height=rect.bottom-rect.top;
left += 326;
PicoSwWnd=CreateWindow("PicoSwWnd","Storyware",style,
left,top,width+160,height,FrameWnd,NULL,NULL,NULL);
top += 266;
PicoPadWnd=CreateWindow("PicoPadWnd","Drawing Pad",style,
left,top,width,height,FrameWnd,NULL,NULL,NULL);
return 0;
}
// --------------------
static DWORD WINAPI ThreadCode(void *)
{
LoopCode();
return 0;
}
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR cmdline,int)
{
MSG msg;
int ret=0;
DWORD tid=0;
HANDLE thread=NULL;
FrameInit();
ret=LoopInit(); if (ret) goto end0;
// Make another thread to run LoopCode():
LoopQuit=0;
LoopWait=1; // wait for ROM to be loaded
thread=CreateThread(NULL,0,ThreadCode,NULL,0,&tid);
LoadROM(cmdline);
// Main window loop:
for (;;)
{
GetMessage(&msg,NULL,0,0);
if (msg.message==WM_QUIT) break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// Signal thread to quit and wait for it to exit:
LoopQuit=1; WaitForSingleObject(thread,5000);
CloseHandle(thread); thread=NULL;
end0:
LoopExit();
DestroyWindow(FrameWnd);
_CrtDumpMemoryLeaks();
return 0;
}
extern void error(char *text)
{
MessageBox(FrameWnd, text, "Error", 0);
}

View file

@ -1,79 +0,0 @@
# Makefile for MS Visual C
R=..\..\..\
CFLAGS=/nologo /W2 /O2 /D "_CRT_SECURE_NO_WARNINGS" -I. -I$(R) -I$(R)zlib\
LDFLAGS=/nologo /machine:I386 /opt:nowin98 /out:PicoDrive.exe
CFLAGS=$(CFLAGS) /DEMU_F68K
CFLAGS=$(CFLAGS) /D_USE_CZ80
# debug
#CFLAGS=$(CFLAGS) /Gi
#LDFLAGS=$(LDFLAGS) /DEBUG
# emu
OBJ = Emu.obj Input.obj Main.obj Direct.obj DSound.obj Loop.obj
# TexScreen.obj
# common
#OBJS += platform\common\emu.obj platform\common\menu.obj platform\common\fonts.obj
# platform\common\mp3_helix.obj
OBJ = $(OBJ) $(R)platform\common\readpng.obj $(R)platform\common\config.obj
# Pico
OBJ = $(OBJ) $(R)Pico\Area.obj $(R)Pico\Cart.obj $(R)Pico\Memory.obj $(R)Pico\Misc.obj $(R)Pico\Pico.obj $(R)Pico\Sek.obj \
$(R)Pico\VideoPort.obj $(R)Pico\Draw2.obj $(R)Pico\Draw.obj $(R)Pico\Patch.obj
# Pico - CD
OBJ = $(OBJ) $(R)Pico\cd\Pico.obj $(R)Pico\cd\Memory.obj $(R)Pico\cd\Sek.obj $(R)Pico\cd\LC89510.obj \
$(R)Pico\cd\cd_sys.obj $(R)Pico\cd\cd_file.obj $(R)Pico\cd\gfx_cd.obj \
$(R)Pico\cd\Area.obj $(R)Pico\cd\Misc.obj $(R)Pico\cd\pcm.obj $(R)Pico\cd\buffering.obj \
$(R)Pico\cd\cue.obj
# Pico - Pico
OBJ = $(OBJ) $(R)Pico\Pico\Pico.obj $(R)Pico\Pico\Memory.obj $(R)Pico\Pico\xpcm.obj
# Pico - sound
OBJ = $(OBJ) $(R)Pico\sound\sound.obj $(R)Pico\sound\sn76496.obj $(R)Pico\sound\ym2612.obj $(R)Pico\sound\mix.obj
# Pico - carthw
OBJ = $(OBJ) $(R)Pico\carthw\carthw.obj $(R)Pico\carthw\svp\svp.obj $(R)Pico\carthw\svp\Memory.obj \
$(R)Pico\carthw\svp\ssp16.obj $(R)Pico\carthw\svp\compiler.obj
# zlib
OBJ = $(OBJ) $(R)zlib\gzio.obj $(R)zlib\inffast.obj $(R)zlib\inflate.obj $(R)zlib\inftrees.obj $(R)zlib\trees.obj \
$(R)zlib\deflate.obj $(R)zlib\crc32.obj $(R)zlib\adler32.obj $(R)zlib\zutil.obj $(R)zlib\compress.obj $(R)zlib\uncompr.obj
# unzip
OBJ = $(OBJ) $(R)unzip\unzip.obj $(R)unzip\unzip_stream.obj
# CPU cores
OBJ = $(OBJ) $(R)cpu\fame\famec.obj
# z80
OBJ = $(OBJ) $(R)cpu\cz80\cz80.obj
.c.obj:
cl $(CFLAGS) /c $< /Fo$@
.cpp.obj:
cl $(CFLAGS) /c $< /Fo$@
ALL : PicoDrive.exe
PicoDrive.exe : $(OBJ)
link.exe $(LDFLAGS) $(OBJ) libpng.lib gdi32.lib user32.lib advapi32.lib dsound.lib comdlg32.lib ddraw.lib dxguid.lib
# d3d8.lib d3dx8.lib
clean:
-del $(OBJ) PicoDrive.exe
test.exe : test.cpp
cl $(CFLAGS) test.cpp user32.lib d3dx8.lib d3d8.lib
dxtut1.exe : dxtut1.cpp
cl $(CFLAGS) dxtut1.cpp user32.lib d3d8.lib
# d3dx8.lib

View file

@ -1,108 +0,0 @@
#include "app.h"
IDirect3DTexture8 *TexScreen=NULL;
int TexWidth=0,TexHeight=0;
// Blank the texture:
static int TexBlank()
{
D3DLOCKED_RECT lock={0,NULL};
unsigned char *dest=NULL;
int y=0,line=0;
TexScreen->LockRect(0,&lock,NULL,0); if (lock.pBits==NULL) return 1;
dest=(unsigned char *)lock.pBits;
for (y=0; y<TexHeight; y++,line+=lock.Pitch)
{
memset(dest+line,0,TexWidth<<1);
}
TexScreen->UnlockRect(0);
return 0;
}
int TexScreenInit()
{
TexWidth =512;
TexHeight=512;
Device->CreateTexture(TexWidth,TexHeight,1,0,D3DFMT_R5G6B5,D3DPOOL_MANAGED,&TexScreen);
if (TexScreen==NULL) return 1;
TexBlank();
return 0;
}
void TexScreenExit()
{
RELEASE(TexScreen)
TexWidth=TexHeight=0;
}
// Copy screen to a swizzled texture
int TexScreenSwizzle()
{
D3DLOCKED_RECT lock={0,NULL};
unsigned char *dest=NULL;
int y=0,sy=0,mask=0;
unsigned short *ps=NULL;
mask=TexWidth*TexHeight-1;
TexScreen->LockRect(0,&lock,NULL,0); if (lock.pBits==NULL) return 1;
dest=(unsigned char *)lock.pBits;
ps=EmuScreen;
// Write to swizzled locations:
for (y=0,sy=0; y<EmuHeight; y++,sy++)
{
int x=0,sx=0;
sy|=0x55555555;
for (x=0,sx=0; x<EmuWidth; x++,sx++)
{
int addr=0;
sx|=0xaaaaaaaa;
addr=sx&sy&mask; // Calculate swizzled address
((unsigned short *)dest)[addr]=*ps++;
}
}
TexScreen->UnlockRect(0);
return 0;
}
// Copy screen to a linear texture:
int TexScreenLinear()
{
D3DLOCKED_RECT lock={0,NULL};
unsigned char *dest=NULL;
int y=0,line=0;
unsigned short *ps=NULL;
TexScreen->LockRect(0,&lock,NULL,0);
if (lock.pBits==NULL) return 1;
dest=(unsigned char *)lock.pBits;
ps=EmuScreen;
for (y=0; y<EmuHeight; y++,line+=lock.Pitch)
{
int x=0;
int addr=line;
for (x=0; x<EmuWidth; x++,addr+=2)
{
*(unsigned int *)(dest+addr)=*ps++;
}
}
TexScreen->UnlockRect(0);
return 0;
}

View file

@ -1,85 +0,0 @@
#include <stdio.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <d3d8.h>
#include <d3dx8.h>
#include <pico/pico.h>
#define RELEASE(x) if (x) x->Release(); x=NULL;
#ifndef __FUNCTION__
#define __FUNCTION__ ""
#endif
#define LOGFAIL() lprintf("fail: %s %s:%i\n", __FUNCTION__, __FILE__, __LINE__)
// Emu.cpp
extern unsigned short *EmuScreen;
extern int EmuWidth,EmuHeight;
extern RECT EmuScreenRect;
extern int PicoPadAdd;
int EmuInit();
void EmuExit();
int EmuRomLoad(char *name);
int EmuFrame();
// Input.cpp
struct Input
{
short axis[4];
unsigned char button[16];
unsigned char held[16]; // How long has the button been held
char repeat[16]; // Auto-repeat
};
extern struct Input Inp;
int InputInit();
void InputExit();
int InputUpdate();
int InputLightCal(int cx,int cy,int ux,int uy);
// Loop.cpp
extern char LoopQuit,LoopWait,LoopWaiting;
extern int LoopMode;
int LoopInit();
void LoopExit();
int LoopCode();
//extern "C" int dprintf(char *format, ...);
extern "C" int lprintf(char *format, ...);
// Main.cpp
extern char *romname;
extern HWND FrameWnd;
extern RECT FrameRectMy;
extern int MainWidth,MainHeight;
extern int lock_to_1_1;
extern void error(char *text);
// --------------------------------------------
// Direct.cpp
extern IDirect3DDevice8 *Device;
extern IDirect3DSurface8 *DirectBack; // Back Buffer
int DirectInit();
int DirectClear(unsigned int colour);
int DirectScreen();
int DirectPresent();
void DirectExit();
// DSound.cpp:
int DSoundInit();
void DSoundExit();
int DSoundUpdate();
extern short *DSoundNext; // Buffer for next sound data to put in loop
// TexScreen.cpp
extern IDirect3DTexture8 *TexScreen;
extern int TexWidth,TexHeight;
int TexScreenInit();
void TexScreenExit();
int TexScreenSwizzle();
int TexScreenLinear();

View file

@ -1,19 +0,0 @@
// port specific settings
#ifndef PORT_CONFIG_H
#define PORT_CONFIG_H
// draw2.c
#define START_ROW 0 // which row of tiles to start rendering at?
#define END_ROW 28 // ..end
#define SIMPLE_WRITE_SOUND 1
#define mix_32_to_16l_stereo_lvl mix_32_to_16l_stereo
// pico.c
#define CAN_HANDLE_240_LINES 0
#define dprintf
#define strcasecmp stricmp
#endif //PORT_CONFIG_H

View file

@ -1,61 +0,0 @@
About
-----
This is a quick windows port of PicoDrive, a Megadrive / Genesis emulator for
handheld devices. It was originally coded having ARM CPU based devices in mind
(most work was done on GP2X version), but there is also a PSP port.
The sole purpose of this port is to demonstrate my SVP and Sega Pico emulation
code. This makes it one of the most minimal emulators out there. If you need
more features, you will have to wait until support is integrated in Kega,
Gens and the likes, as this emu was not meant to compete with them.
For more info, visit http://notaz.gp2x.de/svp.php
Releases
--------
1.40 - first release.
1.40a - Tasco Deluxe's dithering fix.
1.40b - Perspective fix thanks to Pierpaolo Prazzoli's info.
1.45 - Added preliminary Sega Pico emulation.
1.45a - Few bugfixes and additions.
Controls
--------
These are currently hardcoded, keyboard only:
PC Gen/MD Sega Pico
-------+-----------+---------
Enter: Start
Z: A
X: B red button
C: C pen push
TAB: (reset)
Esc: (load ROM)
Arrows: D-pad
Credits
-------
A lot of work on making SVP emulation happen was done by Tasco Deluxe, my
stuff is a continuation of his. Pierpaolo Prazzoli's information and his
SSP1610 disassembler in MAME code helped a lot too.
The original PicoDrive was written by fDave from finalburn.com
This PicoDrive version uses bits and pieces of from other projects:
68k: FAME/C core, by Chui and Stéphane Dallongeville (as C68K).
z80: CZ80 by Stéphane Dallongeville and modified by NJ.
YM2612 and SN76496 cores: MAME devs.
Special thanks to Rokas and Lordus for various ideas.
Greets to all the sceners and emu authors out there!

View file

@ -1,2 +0,0 @@
#define VERSION "1.45a"