lots of win32 port work

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@343 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2008-02-03 20:28:48 +00:00
parent e0978fa87d
commit 1b0ac8adc9
20 changed files with 307 additions and 2870 deletions

View file

@ -18,7 +18,7 @@ static int LoopBlank()
void *mema=NULL,*memb=NULL;
DWORD sizea=0,sizeb=0;
LoopBuffer->Lock(0,LoopLen<<2, &mema,&sizea, &memb,&sizeb, 0);
LoopBuffer->Lock(0,LoopLen<<((PicoOpt&8) ? 2 : 1), &mema,&sizea, &memb,&sizeb, 0);
if (mema) memset(mema,0,sizea);
@ -47,6 +47,7 @@ int DSoundInit()
// 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);
// dprintf2("p %p\n", DSoundNext);
// Create the DirectSound interface:
DirectSoundCreate(NULL,&DSound,NULL);
@ -78,32 +79,57 @@ void DSoundExit()
if (LoopBuffer) LoopBuffer->Stop();
RELEASE(LoopBuffer)
RELEASE(DSound)
free(DSoundNext); DSoundNext=NULL;
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
LoopBuffer->Lock(LoopWrite<<((PicoOpt&8) ? 2 : 1),PsndLen<<((PicoOpt&8) ? 2 : 1), &mema,&sizea, &memb,&sizeb, 0);
ret = LoopBuffer->Lock(LoopWrite<<((PicoOpt&8) ? 2 : 1),PsndLen<<((PicoOpt&8) ? 2 : 1), &mema,&sizea, &memb,&sizeb, 0);
if (ret) dprintf2("LoopBuffer->Lock() failed: %i\n", ret);
if (mema) memcpy(mema,DSoundNext,sizea);
// if (memb) memcpy(memb,DSoundNext+sizea,sizeb);
if (sizeb != 0) dprintf2("sizeb is not 0! (%i)\n", sizeb);
LoopBuffer->Unlock(mema,sizea, memb,0);
ret = LoopBuffer->Unlock(mema,sizea, memb,0);
if (ret) dprintf2("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)
{
while (diff >= 0 && diff < 1000000/60)
{
Sleep(1);
diff = GetTickCount()*1000 - ticks_old;
}
ticks_old = ticks + 1000000/60;
}
else
ticks_old = ticks;
return 0;
}
int DSoundUpdate()
{
DWORD play=0;
int pos=0;
if (LoopBuffer==NULL) return -1;
if (LoopBuffer==NULL) return DSoundFake();
LoopBuffer->GetCurrentPosition(&play,NULL);
pos=play>>((PicoOpt&8) ? 2 : 1);
@ -120,14 +146,3 @@ int DSoundUpdate()
return 0;
}
void DSoundMute()
{
if (LoopBuffer==NULL) return;
LoopBuffer->Stop();
}
void DSoundUnMute()
{
if (LoopBuffer==NULL) return;
LoopBuffer->Play(0,0,DSBPLAY_LOOPING);
}

View file

@ -1,5 +1,6 @@
#include "app.h"
#ifdef USE_D3D
// d3d
static IDirect3D8 *Direct3D=NULL;
IDirect3DDevice8 *Device=NULL;
@ -16,6 +17,7 @@ struct CustomVertex
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
static CustomVertex VertexList[4];
#endif
// ddraw
#include <ddraw.h>
@ -144,7 +146,7 @@ static int DirectClearDDraw(unsigned int colour)
static int DirectPresentDDraw()
{
int ret = m_pddsFrontBuffer->Blt(&FrameRectMy, m_pddsBackBuffer, NULL, DDBLT_WAIT, NULL);
int ret = m_pddsFrontBuffer->Blt(&FrameRectMy, m_pddsBackBuffer, &EmuScreenRect, DDBLT_WAIT, NULL);
if (ret) { LOGFAIL(); return 1; }
return 0;
}
@ -154,6 +156,7 @@ static int DirectPresentDDraw()
int DirectInit()
{
#if USE_D3D
D3DPRESENT_PARAMETERS d3dpp;
D3DDISPLAYMODE mode;
int i,u,ret=0;
@ -242,14 +245,14 @@ fail0:
RELEASE(Direct3D)
// error("Failed to use Direct3D, trying DirectDraw..");
#endif
// try DirectDraw
return DirectDrawInit();
}
void DirectExit()
{
//FontExit();
#ifdef USE_D3D
TexScreenExit();
// d3d
@ -257,11 +260,35 @@ void DirectExit()
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
static int MakeVertexList()
{
struct CustomVertex *vert=NULL,*pv=NULL;
@ -303,24 +330,6 @@ static int MakeVertexList()
return 0;
}
int DirectClear(unsigned int colour)
{
if (Device == NULL)
return DirectClearDDraw(colour);
Device->Clear(0,NULL,D3DCLEAR_TARGET,colour,1.0f,0);
return 0;
}
int DirectPresent()
{
if (Device == NULL)
return DirectPresentDDraw();
Device->Present(NULL,NULL,NULL,NULL);
return 0;
}
static int SetupMatrices()
{
D3DXVECTOR3 eye ( 0.0f, 0.0f, 0.0f );
@ -387,3 +396,10 @@ int DirectScreen()
return 0;
}
#else
int DirectScreen()
{
return DirectScreenDDraw();
}
#endif

View file

@ -3,6 +3,8 @@
unsigned short *EmuScreen=NULL;
int EmuWidth=320,EmuHeight=224;
RECT EmuScreenRect = { 0, 0, 320, 224 };
static int EmuScan(unsigned int num, void *sdata);
unsigned char *PicoDraw2FB = NULL;
@ -38,16 +40,16 @@ void EmuExit()
// Megadrive scanline callback:
static int EmuScan(unsigned int num, void *sdata)
{
unsigned short *pd=NULL,*end=NULL;
unsigned short *pd=NULL;
unsigned short *ps=NULL;
if (num>=(unsigned int)EmuHeight) return 0;
// Copy scanline to screen buffer:
pd=EmuScreen+(num<<8)+(num<<6); end=pd+320;
pd=EmuScreen+(num<<8)+(num<<6);
ps=(unsigned short *)sdata;
do { *pd++=*ps++; } while (pd<end);
memcpy(pd, ps, 320*2);
return 0;
}
@ -68,7 +70,7 @@ int EmuFrame()
PsndOut=(short *)DSoundNext;
PicoFrame();
//PsndOut=NULL;
PsndOut=NULL;
return 0;
}

View file

@ -1,188 +0,0 @@
#include "app.h"
#include "FileMenu.h"
class FileMenu FileMenu;
FileMenu::FileMenu()
{
memset(this,0,sizeof(*this));
}
int FileMenu::init()
{
memset(this,0,sizeof(*this));
strcpy(currentPath,HOME "roms");
return 0;
}
int FileMenu::scan()
{
char path[260];
memset(path,0,sizeof(path));
// Scan for all the roms in the current directory:
nameReset();
sprintf(path,"%.240s\\*.bin", currentPath); nameFind(path);
sprintf(path,"%.240s\\*.smd", currentPath); nameFind(path);
sprintf(path,"%.240s\\*.zip",currentPath); nameFind(path);
return 0;
}
void FileMenu::exit()
{
free(nameList);
memset(this,0,sizeof(*this));
}
int FileMenu::render()
{
int x=0,y=0;
int pos=0,index=0;
WCHAR text[64];
int height=24;
memset(text,0,sizeof(text));
x=120; y=224;
y-=(choiceFocus*height)>>8;
while (pos<nameSize)
{
char *name=NULL;
name=nameList+pos;
if (y>-height && y<MainHeight)
{
unsigned int colour=0xffffff;
// If this line is visible:
wsprintfW(text,L"%.42S",name);
if (index==(choiceFocus>>8)) colour=0x00ff40;
FontSetColour(colour);
FontText(text,x,y);
}
y+=height;
pos+=strlen(name)+1; // Skip to next string
index++;
}
return 0;
}
int FileMenu::scroll(int amount)
{
int max=0;
choiceFocus+=amount;
max=nameCount<<8;
if (choiceFocus<0) choiceFocus=0;
if (choiceFocus>=max) choiceFocus=max-1;
return 0;
}
// Get the currently highlighted filename
int FileMenu::getFilePath(char *path)
{
int focus=0;
int pos=0;
char *name=NULL;
// Find where the user is focused
focus=choiceFocus>>8;
pos=nameOffset(focus); if (pos<0) return 1;
name=nameList+pos;
// Return path and name:
sprintf(path,"%.128s\\%.128s",currentPath,name);
return 0;
}
// ----------------------------------------------------------------------
int FileMenu::nameReset()
{
free(nameList); nameList=NULL;
nameSize=nameMax=nameCount=0;
return 0;
}
int FileMenu::nameFind(char *path)
{
HANDLE find=NULL;
WIN32_FIND_DATA wfd;
memset(&wfd,0,sizeof(wfd));
find=FindFirstFile(path,&wfd);
if (find==INVALID_HANDLE_VALUE) return 1;
for (;;)
{
nameAdd(wfd.cFileName); // Add the name to the list
if (FindNextFile(find,&wfd)==0) break;
}
FindClose(find);
return 0;
}
int FileMenu::nameAdd(char *entry)
{
int len=0;
len=strlen(entry);
// Check we have room for this entry:
if (nameSize+len+1>nameMax) nameSizeUp();
if (nameSize+len+1>nameMax) return 1;
// Add entry with zero at the end:
memcpy(nameList+nameSize,entry,len);
nameSize+=len+1;
nameCount++;
return 0;
}
int FileMenu::nameSizeUp()
{
void *mem=NULL;
int add=256;
// Allocate more memory for the list:
mem=realloc(nameList,nameMax+add); if (mem==NULL) return 1;
nameList=(char *)mem;
memset(nameList+nameMax,0,add); // Blank new memory
nameMax+=add;
return 0;
}
int FileMenu::nameOffset(int index)
{
int pos=0,i=0;
while (pos<nameSize)
{
char *name=nameList+pos;
if (i==index) return pos;
pos+=strlen(name)+1; // Skip to next string
i++;
}
return -1; // Unknown index
}

View file

@ -1,29 +0,0 @@
// FileMenu.cpp
class FileMenu
{
public:
FileMenu();
int init();
int scan();
void exit();
int render();
int scroll(int amount);
int getFilePath(char *name);
private:
int nameReset();
int nameFind(char *path);
int nameAdd(char *entry);
int nameSizeUp();
int nameOffset(int index);
char currentPath[260];
char *nameList;
int nameSize,nameMax;
int nameCount;
int choiceFocus;
};
extern class FileMenu FileMenu;

View file

@ -1,85 +0,0 @@
#include "app.h"
// ----------------------------------------------------------------------------------
#ifdef _XBOX
#include <xfont.h>
static XFONT *Font=NULL;
int FontInit()
{
XFONT_OpenDefaultFont(&Font); if (Font==NULL) return 1;
return 0;
}
void FontExit()
{
}
int FontSetColour(unsigned int colour)
{
Font->SetTextColor(colour);
return 0;
}
int FontText(WCHAR *text,int dx,int dy)
{
if (Font==NULL || DirectBack==NULL) return 1;
Font->TextOut(DirectBack,text,~0U,dx,dy);
return 0;
}
#endif
// ----------------------------------------------------------------------------------
#ifndef _XBOX
static ID3DXFont *Font=NULL;
static unsigned int FontColour=0;
int FontInit()
{
LOGFONT lf;
memset(&lf,0,sizeof(lf));
strcpy(lf.lfFaceName,"Arial");
lf.lfHeight=24;
D3DXCreateFontIndirect(Device,&lf,&Font);
return 0;
}
void FontExit()
{
RELEASE(Font);
}
int FontSetColour(unsigned int colour)
{
FontColour=0xff000000|colour;
return 0;
}
int FontText(WCHAR *text,int dx,int dy)
{
RECT rect={0,0,0,0};
if (Font==NULL || DirectBack==NULL) return 1;
Font->Begin();
rect.left=dx;
rect.top=dy;
rect.right=MainWidth;
rect.bottom=MainHeight;
Font->DrawTextW(text,-1,&rect,DT_LEFT,FontColour);
Font->End();
return 0;
}
#endif

View file

@ -1,308 +0,0 @@
# Microsoft Developer Studio Project File - Name="GenaDrive" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=GenaDrive - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "GenaDrive.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "GenaDrive.mak" CFG="GenaDrive - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "GenaDrive - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "GenaDrive - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "GenaDrive - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\..\..\Pico" /I ".\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "EMU_M68K" /D "_USE_MZ80" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 gdi32.lib user32.lib advapi32.lib d3d8.lib d3dx8.lib dsound.lib comdlg32.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "GenaDrive - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\..\..\Pico" /I ".\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "DEBUG" /D "EMU_M68K" /D "_USE_MZ80" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 user32.lib gdi32.lib advapi32.lib d3d8.lib d3dx8.lib dsound.lib comdlg32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "GenaDrive - Win32 Release"
# Name "GenaDrive - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\Emu.cpp
# End Source File
# Begin Source File
SOURCE=.\GenaDrive.txt
# End Source File
# Begin Source File
SOURCE=.\Input.cpp
# End Source File
# Begin Source File
SOURCE=.\LightCal.cpp
# End Source File
# Begin Source File
SOURCE=.\Loop.cpp
# End Source File
# Begin Source File
SOURCE=.\Main.cpp
# End Source File
# Begin Source File
SOURCE=.\Makefile
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\app.h
# End Source File
# End Group
# Begin Group "DirectX"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\Direct.cpp
# End Source File
# Begin Source File
SOURCE=.\DSound.cpp
# End Source File
# Begin Source File
SOURCE=.\FileMenu.cpp
# End Source File
# Begin Source File
SOURCE=.\FileMenu.h
# End Source File
# Begin Source File
SOURCE=.\Font.cpp
# End Source File
# Begin Source File
SOURCE=.\TexScreen.cpp
# End Source File
# End Group
# Begin Group "Pico"
# PROP Default_Filter ""
# Begin Group "sound"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\..\Pico\sound\driver.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Pico\sound\sn76496.c
# End Source File
# Begin Source File
SOURCE=..\..\..\Pico\sound\sn76496.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Pico\sound\sound.c
# End Source File
# Begin Source File
SOURCE=..\..\..\Pico\sound\sound.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Pico\sound\ym2612.c
# End Source File
# Begin Source File
SOURCE=..\..\..\Pico\sound\ym2612.h
# End Source File
# End Group
# Begin Source File
SOURCE=..\..\..\Pico\Area.c
# End Source File
# Begin Source File
SOURCE=..\..\..\Pico\Cart.c
# End Source File
# Begin Source File
SOURCE=..\..\..\Pico\Draw.c
# End Source File
# Begin Source File
SOURCE=..\..\..\Pico\Draw2.c
# End Source File
# Begin Source File
SOURCE=..\..\..\Pico\Memory.c
# End Source File
# Begin Source File
SOURCE=..\..\..\Pico\Misc.c
# End Source File
# Begin Source File
SOURCE=..\..\..\Pico\Pico.c
# End Source File
# Begin Source File
SOURCE=..\..\..\Pico\Pico.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Pico\PicoInt.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Pico\Sek.c
# End Source File
# Begin Source File
SOURCE=..\..\..\Pico\Utils.c
# End Source File
# Begin Source File
SOURCE=..\..\..\Pico\VideoPort.c
# End Source File
# End Group
# Begin Group "cores"
# PROP Default_Filter ""
# Begin Group "musashi"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\..\cpu\musashi\m68k.h
# End Source File
# Begin Source File
SOURCE=..\..\..\cpu\musashi\m68kconf.h
# End Source File
# Begin Source File
SOURCE=..\..\..\cpu\musashi\m68kcpu.c
# End Source File
# Begin Source File
SOURCE=..\..\..\cpu\musashi\m68kcpu.h
# End Source File
# Begin Source File
SOURCE=..\..\..\cpu\musashi\m68kdasm.c
# End Source File
# Begin Source File
SOURCE=..\..\..\cpu\musashi\m68kopac.c
# End Source File
# Begin Source File
SOURCE=..\..\..\cpu\musashi\m68kopdm.c
# End Source File
# Begin Source File
SOURCE=..\..\..\cpu\musashi\m68kopnz.c
# End Source File
# Begin Source File
SOURCE=..\..\..\cpu\musashi\m68kops.c
# End Source File
# Begin Source File
SOURCE=..\..\..\cpu\musashi\m68kops.h
# End Source File
# End Group
# Begin Source File
SOURCE=..\..\..\cpu\mz80\mz80.obj
# End Source File
# Begin Source File
SOURCE=..\..\..\cpu\a68k\a68k.obj
!IF "$(CFG)" == "GenaDrive - Win32 Release"
!ELSEIF "$(CFG)" == "GenaDrive - Win32 Debug"
# PROP Exclude_From_Build 1
!ENDIF
# End Source File
# End Group
# End Target
# End Project

View file

@ -1,118 +0,0 @@
__________________________________________________________________________________________
______ _______ __ _ _______ ______ ______ _____ _ _ _______
| ____ |______ | \ | |_____| | \ |_____/ | \ / |______
|_____| |______ | \_| | | |_____/ | \_ __|__ \/ |______
G E N A D R I V E
GenaDrive is a Genesis / MegaDrive emulator for the XBox.
#include <std_disclaimer.h>
I do not accept responsibility for any effects, adverse or otherwise, that
this code may have on you, your computer, your sanity, your dog... etc.
You can use this software freely as long as you don't use it commercially.
__________________________________________________________________________________________
Weird Name?
GenaDrive is a porn-star emulator, based on legendary porn star Jenna Ja... no not really.
GenaDrive (one word, capital G, capital D), is pronounced "Jen-A-Drive".
(Think 'MegaDrive' but with 'Gen' instead of 'Meg'.)
__________________________________________________________________________________________
What's New
v0.004
* Merged the PicoDrive and GenaDrive 'Pico' directories, with ifdefs for
EMU_C68K (Cyclone) and EMU_A68K.
v0.003 - Added .SMD support
v0.002 - First release
__________________________________________________________________________________________
Okay but what is it?
GenaDrive is a partially-complete MegaDrive emulator for the XBox. It emulates the
hardware of the MegaDrive console on the XBox. Basically, it makes your XBox act like
a MegaDrive.
It actually uses the same code-base as my Pocket PC 'PicoDrive' emulator, but instead
of an ARM-optimized 68000 emulator it uses (naturally) an Intel-optimized one - A68K
from the MAME project.
__________________________________________________________________________________________
How to use
Put the emulator (default.xbe) in a directory such as e:\Emulators\GenaDrive\
Make sure there is a directory e:\Emulators\GenaDrive\Roms
Put your rom images there.
Run GenaDrive.
If it doesn't work, try running 'xbepatch' on the XBE first to convert it to a retail XBE.
This is minimal zip support, though there must be no other files in each zip.
Run the emulator and you will see a list of rom images. Push up/down and press A
to select a rom image.
Click the Right thumbstick in to pause and return to the menu.
To exit the emulator hold L and R and press Black, or press Back+Start.
This is just an early version so there's quite a few things missing or not up to scratch,
e.g. sound, z80, joypad 2
__________________________________________________________________________________________
What's currently emulated:
68000 : Yes
VDP
Scroll A/B : Yes
Line Scroll : Yes
Sprites : Sort of
Window : Not yet
H-Ints/HV Counter : Not yet
Sound:
Z80 : Not yet (faked)
YM2151 : Not yet
PSG : Not yet
Compatibility: ~50% ?
__________________________________________________________________________________________
Web page and contact info:
I (Dave) can be reached at the usual spot, my web-page is:
http://www.finalburn.com/
And my e-mail address is as follows, just change the (atsymbol) to @
dev(atsymbol)finalburn.com
NB - I had to shut down the 'dave' mailbox so it's now 'dev', because the 'dave'
e-mail address was printed everywhere and spambots logged it and spammed it to death! :P
So if you must quote it, please quote it as above... or better yet just link to my webpage.
Thanks to:
Mike Coates and Darren Olafson once again for A68K
Sam for getting me set up on my XBox!
Charles Macdonald, for researching just about every console ever
MameDev+FBA, for keeping on going and going and going
XPort for loads of great XBox emulators
...and anyone else I forgot!
__________________________________________________________________________________________

View file

@ -91,56 +91,17 @@ static int DeviceRead()
if (GetAsyncKeyState('F')) Inp.button[14]=0xff;
static int sblobked = 0;
if(!sblobked && GetAsyncKeyState(VK_F6)) {
FILE *PmovFile;
romname[strlen(romname)-3] = 0;
strcat(romname, "mds");
PmovFile = fopen(romname, "wb");
if(PmovFile) {
PmovState(5, PmovFile);
fclose(PmovFile);
}
sblobked = 1;
}
else if(!sblobked && GetAsyncKeyState(VK_F9)) {
FILE *PmovFile;
romname[strlen(romname)-3] = 0;
strcat(romname, "mds");
PmovFile = fopen(romname, "rb");
if(PmovFile) {
PmovState(6, PmovFile);
fclose(PmovFile);
}
sblobked = 1;
}
else if(!sblobked && GetAsyncKeyState(VK_TAB)) {
if (!sblobked && GetAsyncKeyState(VK_TAB)) {
PicoReset(0);
sblobked = 1;
}
else if(!sblobked && GetAsyncKeyState(VK_ESCAPE))
else if (!sblobked && GetAsyncKeyState(VK_ESCAPE))
{
unsigned char *rom_data;
unsigned int rom_size;
DSoundMute();
pm_file *rom = 0;
OPENFILENAME of; ZeroMemory(&of, sizeof(OPENFILENAME));
of.lStructSize = sizeof(OPENFILENAME);
of.lpstrFilter = "ROMs\0*.smd;*.bin;*.gen\0";
of.lpstrFile = romname; romname[0] = 0;
of.nMaxFile = MAX_PATH;
of.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
GetOpenFileName(&of);
rom = pm_open(romname);
DSoundUnMute();
if(!rom) return 1;
PicoCartLoad(rom, &rom_data, &rom_size);
PicoCartInsert(rom_data, rom_size);
pm_close(rom);
PostMessage(FrameWnd, WM_COMMAND, 0x20000 | 1000, 0);
sblobked = 1;
}
else
sblobked = GetAsyncKeyState(VK_F6) | GetAsyncKeyState(VK_F9) |
GetAsyncKeyState(VK_TAB) | GetAsyncKeyState(VK_ESCAPE);
sblobked = GetAsyncKeyState(VK_TAB) | GetAsyncKeyState(VK_ESCAPE);
return 0;
}

View file

@ -1,102 +0,0 @@
#include "app.h"
struct Target
{
int sx,sy; // Onscreen coordinates
int dx,dy; // Device values
};
struct Target Targ[2]=
{
{0,0, 0,0},
{0,0, 0,0}
};
static int LightState=0;
struct Calib
{
float ax,bx;
float ay,by;
};
static struct Calib Cal={0.0f,0.0f,0.0f,0.0f};
int LightCalReset()
{
LightState=0;
memset(Targ,0,sizeof(Targ));
Targ[0].sx=MainWidth >>1;
Targ[0].sy=MainHeight>>1;
Targ[1].sy=Targ[0].sy-MainHeight*61/160;
Targ[1].sx=Targ[0].sx-MainWidth *61/160;
return 0;
}
int LightCalUpdate()
{
int i=0;
struct Target *pt=NULL;
if (Inp.held[4]==1) LoopMode=3;
if (Inp.held[8]==1)
{
i=LightState&1;
pt=Targ+i;
pt->dx=Inp.axis[0];
pt->dy=Inp.axis[1];
if (i==1)
{
int num=0,den=0;
// rx= a + b*x - work out a and b:
num=Targ[0].sx-Targ[1].sx;
den=Targ[0].dx-Targ[1].dx;
if (den) Cal.bx=(float)num/(float)den;
Cal.ax=(float)Targ[0].sx-Cal.bx*(float)Targ[0].dx;
num=Targ[0].sy-Targ[1].sy;
den=Targ[0].dy-Targ[1].dy;
if (den) Cal.by=(float)num/(float)den;
Cal.ay=(float)Targ[0].sy-Cal.by*(float)Targ[0].dy;
}
LightState++;
}
return 0;
}
int LightCalRender()
{
int i=0;
struct Target *pt=NULL;
float fx=0.0f,fy=0.0f;
DirectClear(0xffffff);
WCHAR text[80]={0};
wsprintfW(text,L"LightGun Calibration");
FontSetColour(0x0000ff);
FontText(text,240,48);
wsprintfW(text,L"Start to quit, B to call InputLightCal");
FontSetColour(0x004000);
FontText(text,64,120);
i=LightState&1;
pt=Targ+i;
FontSetColour(0);
FontText(L"X", pt->sx-8, pt->sy-12);
fx=Cal.ax+Cal.bx*(float)Inp.axis[0];
fy=Cal.ay+Cal.by*(float)Inp.axis[1];
FontSetColour(0xff0000);
FontText(L"+", (int)fx-8,(int)fy-12);
return 0;
}

View file

@ -1,7 +1,7 @@
#include "app.h"
//#include "FileMenu.h"
char LoopQuit=0;
char LoopQuit=0,LoopWait=0,LoopWaiting=0;
static FILE *DebugFile=NULL;
int LoopMode=0;
static void UpdateSound(int len);
@ -24,10 +24,10 @@ int LoopInit()
//DSoundInit();
ret=EmuInit(); if (ret) return 1;
//FileMenu.init();
LoopMode=8;
PicoWriteSound = UpdateSound;
PicoAutoRgnOrder = 0x184;
return 0;
}
@ -38,9 +38,7 @@ void LoopExit()
{
dprintf(debugString());
//FileMenu.exit();
EmuExit();
DSoundExit(); PsndLen=0;
InputExit();
DirectExit();
@ -50,88 +48,28 @@ void LoopExit()
// ----------------------------------------------------------------
static int DoGame()
{
EmuFrame();
if (Inp.held[7]==1) LoopMode=2; // Right thumb = Toggle Menu
return 0;
}
// ----------------------------------------------------------------
/*
static int MenuUpdate()
{
int delta=0;
if (Inp.repeat[0]) delta-=0x100;
if (Inp.repeat[1]) delta+=0x100;
if (Inp.button[14]>30) delta-=Inp.button[14]-30;
if (Inp.button[15]>30) delta+=Inp.button[15]-30;
if (delta) FileMenu.scroll(delta);
if (Inp.held[8]==1 || Inp.held[10]==1 || Inp.held[4]==1) // A, X or Start
{
//RomFree();
//FileMenu.getFilePath(RomName);
//RomLoad();
//LoopMode=8; // Go to game
}
if (Inp.held[7]==1) LoopMode=8; // Right thumb = Toggle Menu
return 0;
}
static int MenuRender()
{
WCHAR text[80]={0};
wsprintfW(text,L"%.40S v%x.%.3x",AppName,PicoVer>>12,PicoVer&0xfff);
FontSetColour(0x60c0ff);
FontText(text,64,48);
FileMenu.render();
return 0;
}
*/
// ----------------------------------------------------------------
static int ModeUpdate()
{
if (Inp.held[14] && Inp.held[15] && Inp.held[12]==1) LoopQuit=1; // L+R+black to quit:
if (Inp.button[4]>30 && Inp.button[5]>30) LoopQuit=1; // Start and back to quit
if (LoopMode==8) { DoGame(); return 0; }
// if (DSoundNext) memset(DSoundNext,0,PsndLen<<2);
// if (LoopMode==2) { FileMenu.scan(); LoopMode++; return 0; }
// if (LoopMode==3) { MenuUpdate(); return 0; }
// if (LoopMode==4) { LightCalUpdate(); return 0; }
LoopMode=2; // Unknown mode, go to rom menu
return 0;
}
static int ModeRender()
{
DirectScreen();
// if (LoopMode==3) MenuRender();
// if (LoopMode==4) LightCalRender();
return 0;
}
static void UpdateSound(int len)
{
while (DSoundUpdate() > 0) { Sleep(1); }
while (DSoundUpdate()== 0) { }
//while (DSoundUpdate()== 0) { }
}
static void PostProcess()
{
static int lock_to_1_1_prev = 0, is_40_prev = 0;
int is_40 = PicoGetStat(PS_40_CELL);
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()
@ -140,14 +78,23 @@ int LoopCode()
// Main loop:
while (!LoopQuit)
{
if (LoopWait)
{
DSoundExit();
while (!LoopQuit && LoopWait) { LoopWaiting=1; Sleep(100); }
if (LoopQuit) break;
DSoundInit();
}
InputUpdate();
DirectClear(0);
ModeUpdate();
ModeRender();
EmuFrame();
PostProcess();
DirectScreen();
DirectPresent();
// UpdateSound();
}
DSoundExit();
return 0;
}

View file

@ -3,22 +3,130 @@
#include <crtdbg.h>
#include <commdlg.h>
char *romname;
char *romname=NULL;
HWND FrameWnd=NULL;
RECT FrameRectMy;
int lock_to_1_1 = 1;
int MainWidth=720,MainHeight=480;
static HMENU mdisplay = 0;
static void UpdateRect()
{
WINDOWINFO wi;
memset(&wi, 0, sizeof(wi));
wi.cbSize = sizeof(wi);
GetWindowInfo(FrameWnd, &wi);
FrameRectMy = wi.rcClient;
}
static void LoadROM(const char *cmdpath)
{
static char rompath[MAX_PATH] = { 0, };
static unsigned char *rom_data = NULL;
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);
PicoCartInsert(rom_data_new, rom_size);
if (rom_data) free(rom_data);
rom_data = rom_data_new;
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)
{
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: GetWindowRect(hwnd, &FrameRectMy); break;
case WM_SIZING: UpdateRect(); break;
case WM_COMMAND:
switch (LOWORD(wparam))
{
case 1000: LoadROM(NULL); break;
case 1001: 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);
}
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 1200: break;
case 1300:
MessageBox(FrameWnd, "PicoDrive v" VERSION " (c) notaz, 2006-2008\n"
"SVP 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",
"About", 0);
return 0;
}
break;
}
return DefWindowProc(hwnd,msg,wparam,lparam);
@ -28,6 +136,7 @@ static int FrameInit()
{
WNDCLASS wc;
RECT rect={0,0,0,0};
HMENU mmain, mfile;
int style=0;
int left=0,top=0,width=0,height=0;
@ -46,7 +155,7 @@ static int FrameInit()
// Adjust size of windows based on borders:
style=WS_OVERLAPPEDWINDOW;
AdjustWindowRect(&rect,style,0);
AdjustWindowRect(&rect,style,1);
width =rect.right-rect.left;
height=rect.bottom-rect.top;
@ -58,13 +167,30 @@ static int FrameInit()
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, "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");
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, 1200, "&Config");
InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING|MF_POPUP, 1300, "&About");
// Create the window:
FrameWnd=CreateWindow(wc.lpszClassName,"PicoDrive " VERSION,style|WS_VISIBLE,
left,top,width,height,NULL,NULL,NULL,NULL);
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);
GetWindowRect(FrameWnd, &FrameRectMy);
UpdateRect();
return 0;
}
@ -83,50 +209,17 @@ int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR cmdline,int)
int ret=0;
DWORD tid=0;
HANDLE thread=NULL;
unsigned char *rom_data = 0;
unsigned int rom_size = 0;
static char rompath[MAX_PATH] = { 0, };
pm_file *rom = NULL;
FrameInit();
ret=LoopInit(); if (ret) goto end0;
// notaz: load rom
strcpy(rompath, cmdline + (cmdline[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;
if(!GetOpenFileName(&of)) goto end0;
rom = pm_open(rompath);
if(!rom) goto end0;
}
romname = rompath;
ret=PicoCartLoad(rom, &rom_data, &rom_size);
pm_close(rom);
if (ret) {
error("failed to load ROM");
goto end0;
}
PicoCartInsert(rom_data, rom_size);
// only now we got the mode (pal/ntsc), so init sound now
ret=DSoundInit();
if (ret) error("Failed to init DirectSound"); // warning
// 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 (;;)
{
@ -145,8 +238,6 @@ end0:
LoopExit();
DestroyWindow(FrameWnd);
free(rom_data);
_CrtDumpMemoryLeaks();
return 0;
}

View file

@ -10,10 +10,15 @@ CFLAGS=$(CFLAGS) /DEMU_F68K
CFLAGS=$(CFLAGS) /D_USE_CZ80
# emu
OBJ = Emu.obj Input.obj Main.obj Direct.obj DSound.obj Loop.obj TexScreen.obj
# debug
#CFLAGS=$(CFLAGS) /Gi
# not used: Rom.obj Font.obj FileMenu.obj LightCal.obj
#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
@ -51,7 +56,9 @@ OBJ = $(OBJ) $(R)cpu\cz80\cz80.obj
ALL : PicoDrive.exe
PicoDrive.exe : $(OBJ)
link.exe $(LDFLAGS) $(OBJ) gdi32.lib user32.lib advapi32.lib d3d8.lib d3dx8.lib dsound.lib comdlg32.lib ddraw.lib dxguid.lib
link.exe $(LDFLAGS) $(OBJ) gdi32.lib user32.lib advapi32.lib dsound.lib comdlg32.lib ddraw.lib dxguid.lib
# d3d8.lib d3dx8.lib
clean:
-del $(OBJ) PicoDrive.exe

View file

@ -1,143 +0,0 @@
#include "app.h"
#include "Unzip.h"
unsigned char *RomData=NULL;
int RomLen=0;
char RomName[260]="";
static int Byteswap(unsigned char *data,int len)
{
int i=0;
if (len<2) return 1; // Too short
do
{
unsigned short *pd=(unsigned short *)(data+i);
int word=*pd; // Get word
word=(word<<8)|(word>>8); // Byteswap it
*pd=(unsigned short)word; // Put word
i+=2;
}
while (i+2<=len);
return 0;
}
// Interleve a 16k block and byteswap
static int InterleveBlock(unsigned char *dest,unsigned char *src)
{
int i=0;
for (i=0;i<0x2000;i++) dest[(i<<1) ]=src[ i]; // Odd
for (i=0;i<0x2000;i++) dest[(i<<1)+1]=src[0x2000+i]; // Even
return 0;
}
// Decode a SMD file
static int DecodeSmd(unsigned char *data,int len)
{
unsigned char *temp=NULL;
int i=0;
temp=(unsigned char *)malloc(0x4000);
if (temp==NULL) return 1;
memset(temp,0,0x4000);
// Interleve each 16k block and shift down by 0x200:
for (i=0; i+0x4200<=len; i+=0x4000)
{
InterleveBlock(temp,data+0x200+i); // Interleve 16k to temporary buffer
memcpy(data+i,temp,0x4000); // Copy back in
}
free(temp);
return 0;
}
int RomLoad()
{
FILE *file=NULL;
char *name=NULL;
int nameLen=0;
int fileLen=0,space=0;
Unzip unzip;
name=RomName;
file=fopen(name,"rb"); if (file==NULL) return 1;
nameLen=strlen(name);
if (stricmp(name+nameLen-4,".zip")==0) unzip.file=file; // Open as zip file
if (unzip.file)
{
int ret=0;
ret=unzip.fileOpen(); // Get first entry
if (ret==0)
{
fileLen=unzip.dataLen; // Length of file
// Switch to using the name in the zip file:
name=unzip.name; nameLen=strlen(name);
}
else
{
unzip.file=NULL;
}
}
else
{
// Find out the length of the file:
fseek(file,0,SEEK_END); fileLen=ftell(file);
fseek(file,0,SEEK_SET);
}
// Allocate space for it:
space=(fileLen+0x3fff)&~0x3fff;
RomData=(unsigned char *)malloc(space);
if (RomData==NULL) { fclose(file); return 1; }
memset(RomData,0,space);
// Read in file:
if (unzip.file) unzip.fileDecode(RomData);
else fread(RomData,1,fileLen,file);
unzip.fileClose();
fclose(file);
unzip.file=file=NULL;
RomLen=fileLen;
// Check for SMD:
if ((fileLen&0x3fff)==0x200)
{
// Decode and byteswap:
DecodeSmd(RomData,RomLen);
RomLen-=0x200;
}
else
{
// Just byteswap:
Byteswap(RomData,RomLen);
}
PicoCartInsert(RomData,RomLen);
return 0;
}
void RomFree()
{
// PicoCartInsert(NULL,0); // Unplug rom
if (RomData) free(RomData);
RomData=NULL; RomLen=0;
memset(RomName,0,sizeof(RomName));
}

View file

@ -1,109 +0,0 @@
#include "app.h"
#include "Unzip.h"
#include "zlib.h"
// Decompress a 'deflate' compressed buffer
static int Inflate(unsigned char *dest,int destLen, unsigned char *src,int srcLen)
{
z_stream stream;
memset(&stream,0,sizeof(stream));
stream.next_in =src;
stream.avail_in =srcLen;
stream.next_out =dest;
stream.avail_out=destLen;
inflateInit2(&stream,-15);
inflate(&stream,Z_FINISH);
inflateEnd(&stream);
return 0;
}
static int Get32(unsigned char *src)
{
return src[0] | (src[1]<<8) | (src[2]<<16) | (src[3]<<24);
}
// --------------------------------------------------------------
Unzip::Unzip()
{
memset(this,0,sizeof(*this));
}
int Unzip::gotoFirstFile()
{
headerPos=0;
return 0;
}
int Unzip::fileOpen()
{
int ret=0,okay=0;
fseek(file,headerPos,SEEK_SET);
// Read in file entry header:
ret=fread(head,1,sizeof(head),file);
if (ret!=sizeof(head)) return 1;
// Check header:
if (head[0]=='P' && head[1]=='K' && head[2]==3 && head[3]==4) okay=1;
if (okay==0) return 1;
// Get compressed and uncompressed sizes:
srcLen =Get32(head+0x12);
dataLen=Get32(head+0x16);
// Get size of name and extra fields:
nameLen=Get32(head+0x1a);
extraLen=nameLen>>16; nameLen&=0xffff;
// Read in name:
name=(char *)malloc(nameLen+1); if (name==NULL) return 1;
memset(name,0,nameLen+1);
fread(name,1,nameLen,file);
// Find position of compressed data in the file
compPos=headerPos+sizeof(head);
compPos+=nameLen+extraLen;
return 0;
}
int Unzip::fileClose()
{
free(name); name=NULL;
// Go to next header:
headerPos=compPos+srcLen;
srcLen=dataLen=0;
nameLen=extraLen=0;
return 0;
}
int Unzip::fileDecode(unsigned char *data)
{
unsigned char *src=NULL;
// Go to compressed data:
fseek(file,compPos,SEEK_SET);
// Allocate memory:
src=(unsigned char *)malloc(srcLen);
if (src==NULL) { fclose(file); return 1; }
memset(src,0,srcLen);
// Read in compressed version and decompress
fread(src,1,srcLen,file);
Inflate(data,dataLen, src,srcLen);
free(src); src=NULL; srcLen=0;
return 0;
}

View file

@ -1,23 +0,0 @@
class Unzip
{
public:
Unzip();
FILE *file; // Zip file current open
unsigned char head[0x1e]; // Zip entry header
int dataLen; // Zip entry dest (uncompressed) size
char *name; // Name of entry
int gotoFirstFile();
int fileOpen();
int fileClose();
int fileDecode(unsigned char *data);
private:
int srcLen; // Zip entry source (compressed) size
int nameLen,extraLen; // Length of name field and extra fields
int headerPos; // Position of file entry header (PK... etc)
int compPos; // Position of compressed data
};

View file

@ -23,6 +23,7 @@
// Emu.cpp
extern unsigned short *EmuScreen;
extern int EmuWidth,EmuHeight;
extern RECT EmuScreenRect;
int EmuInit();
void EmuExit();
int EmuRomLoad(char *name);
@ -42,13 +43,8 @@ void InputExit();
int InputUpdate();
int InputLightCal(int cx,int cy,int ux,int uy);
// LightCal.cpp
int LightCalReset();
int LightCalUpdate();
int LightCalRender();
// Loop.cpp
extern char LoopQuit;
extern char LoopQuit,LoopWait,LoopWaiting;
extern int LoopMode;
int LoopInit();
@ -62,15 +58,9 @@ extern char *romname;
extern HWND FrameWnd;
extern RECT FrameRectMy;
extern int MainWidth,MainHeight;
extern int lock_to_1_1;
extern void error(char *text);
// Rom.cpp
extern unsigned char *RomData;
extern int RomLen;
extern char RomName[260];
int RomLoad();
void RomFree();
// --------------------------------------------
// Direct.cpp
extern IDirect3DDevice8 *Device;
@ -86,15 +76,6 @@ int DSoundInit();
void DSoundExit();
int DSoundUpdate();
extern short *DSoundNext; // Buffer for next sound data to put in loop
//extern int DSoundSeg; // Seg length in samples
void DSoundMute();
void DSoundUnMute();
// Font.cpp
int FontInit();
void FontExit();
int FontSetColour(unsigned int colour);
int FontText(WCHAR *,int,int);
// TexScreen.cpp
extern IDirect3DTexture8 *TexScreen;

View file

@ -0,0 +1,45 @@
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 emulation code. This
makes it one of the most minimal emulators out there. If you need more
features, you will have to wait until SVP 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
Controls
--------
These are currently hardcoded, keyboard only:
Enter: Start
Z: A
X: B
C: C
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.
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 Stephane Dallongeville (as C68K).
z80: CZ80 by Stephane Dallongeville and modified by NJ.
YM2612 and SN76496 cores: MAME devs.
Greets to all the sceners and emu authors out there!

View file

@ -1,323 +0,0 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2003 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#ifndef ZCONF_H
#define ZCONF_H
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
*/
#ifdef Z_PREFIX
# define deflateInit_ z_deflateInit_
# define deflate z_deflate
# define deflateEnd z_deflateEnd
# define inflateInit_ z_inflateInit_
# define inflate z_inflate
# define inflateEnd z_inflateEnd
# define deflateInit2_ z_deflateInit2_
# define deflateSetDictionary z_deflateSetDictionary
# define deflateCopy z_deflateCopy
# define deflateReset z_deflateReset
# define deflatePrime z_deflatePrime
# define deflateParams z_deflateParams
# define deflateBound z_deflateBound
# define inflateInit2_ z_inflateInit2_
# define inflateSetDictionary z_inflateSetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateCopy z_inflateCopy
# define inflateReset z_inflateReset
# define compress z_compress
# define compress2 z_compress2
# define compressBound z_compressBound
# define uncompress z_uncompress
# define adler32 z_adler32
# define crc32 z_crc32
# define get_crc_table z_get_crc_table
# define Byte z_Byte
# define uInt z_uInt
# define uLong z_uLong
# define Bytef z_Bytef
# define charf z_charf
# define intf z_intf
# define uIntf z_uIntf
# define uLongf z_uLongf
# define voidpf z_voidpf
# define voidp z_voidp
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
# define OS2
#endif
#if defined(_WINDOWS) && !defined(WINDOWS)
# define WINDOWS
#endif
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
# define WIN32
#endif
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
# ifndef SYS16BIT
# define SYS16BIT
# endif
# endif
#endif
/*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int).
*/
#ifdef SYS16BIT
# define MAXSEG_64K
#endif
#ifdef MSDOS
# define UNALIGNED_OK
#endif
#ifdef __STDC_VERSION__
# ifndef STDC
# define STDC
# endif
# if __STDC_VERSION__ >= 199901L
# ifndef STDC99
# define STDC99
# endif
# endif
#endif
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
# define STDC
#endif
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
# define STDC
#endif
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
# define STDC
#endif
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
# define STDC
#endif
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
# define STDC
#endif
#ifndef STDC
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
# define const /* note: need a more gentle solution here */
# endif
#endif
/* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL
#endif
/* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL
# ifdef MAXSEG_64K
# define MAX_MEM_LEVEL 8
# else
# define MAX_MEM_LEVEL 9
# endif
#endif
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
* created by gzip. (Files created by minigzip can still be extracted by
* gzip.)
*/
#ifndef MAX_WBITS
# define MAX_WBITS 15 /* 32K LZ77 window */
#endif
/* The memory requirements for deflate are (in bytes):
(1 << (windowBits+2)) + (1 << (memLevel+9))
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
plus a few kilobytes for small objects. For example, if you want to reduce
the default memory requirements from 256K to 128K, compile with
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
Of course this will generally degrade compression (there's no free lunch).
The memory requirements for inflate are (in bytes) 1 << windowBits
that is, 32K for windowBits=15 (default value) plus a few kilobytes
for small objects.
*/
/* Type declarations */
#ifndef OF /* function prototypes */
# ifdef STDC
# define OF(args) args
# else
# define OF(args) ()
# endif
#endif
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tried only with MSC; for other MSDOS compilers you may have
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
* just define FAR to be empty.
*/
#ifdef SYS16BIT
# if defined(M_I86SM) || defined(M_I86MM)
/* MSC small or medium model */
# define SMALL_MEDIUM
# ifdef _MSC_VER
# define FAR _far
# else
# define FAR far
# endif
# endif
# if (defined(__SMALL__) || defined(__MEDIUM__))
/* Turbo C small or medium model */
# define SMALL_MEDIUM
# ifdef __BORLANDC__
# define FAR _far
# else
# define FAR far
# endif
# endif
#endif
#if defined(WINDOWS) || defined(WIN32)
/* If building or using zlib as a DLL, define ZLIB_DLL.
* This is not mandatory, but it offers a little performance increase.
*/
# ifdef ZLIB_DLL
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
# ifdef ZLIB_INTERNAL
# define ZEXTERN extern __declspec(dllexport)
# else
# define ZEXTERN extern __declspec(dllimport)
# endif
# endif
# endif /* ZLIB_DLL */
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
* define ZLIB_WINAPI.
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
*/
# ifdef ZLIB_WINAPI
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR CDECL
# endif
# endif
#endif
#if defined (__BEOS__)
# ifdef ZLIB_DLL
# ifdef ZLIB_INTERNAL
# define ZEXPORT __declspec(dllexport)
# define ZEXPORTVA __declspec(dllexport)
# else
# define ZEXPORT __declspec(dllimport)
# define ZEXPORTVA __declspec(dllimport)
# endif
# endif
#endif
#ifndef ZEXTERN
# define ZEXTERN extern
#endif
#ifndef ZEXPORT
# define ZEXPORT
#endif
#ifndef ZEXPORTVA
# define ZEXPORTVA
#endif
#ifndef FAR
# define FAR
#endif
#if !defined(__MACTYPES__)
typedef unsigned char Byte; /* 8 bits */
#endif
typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */
#ifdef SMALL_MEDIUM
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
# define Bytef Byte FAR
#else
typedef Byte FAR Bytef;
#endif
typedef char FAR charf;
typedef int FAR intf;
typedef uInt FAR uIntf;
typedef uLong FAR uLongf;
#ifdef STDC
typedef void const *voidpc;
typedef void FAR *voidpf;
typedef void *voidp;
#else
typedef Byte const *voidpc;
typedef Byte FAR *voidpf;
typedef Byte *voidp;
#endif
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
# include <sys/types.h> /* for off_t */
# include <unistd.h> /* for SEEK_* and off_t */
# ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# define z_off_t off_t
#endif
#ifndef SEEK_SET
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
#endif
#ifndef z_off_t
# define z_off_t long
#endif
#if defined(__OS400__)
#define NO_vsnprintf
#endif
#if defined(__MVS__)
# define NO_vsnprintf
# ifdef FAR
# undef FAR
# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__)
# pragma map(deflateInit_,"DEIN")
# pragma map(deflateInit2_,"DEIN2")
# pragma map(deflateEnd,"DEEND")
# pragma map(deflateBound,"DEBND")
# pragma map(inflateInit_,"ININ")
# pragma map(inflateInit2_,"ININ2")
# pragma map(inflateEnd,"INEND")
# pragma map(inflateSync,"INSY")
# pragma map(inflateSetDictionary,"INSEDI")
# pragma map(compressBound,"CMBND")
# pragma map(inflate_table,"INTABL")
# pragma map(inflate_fast,"INFA")
# pragma map(inflate_copyright,"INCOPY")
#endif
#endif /* ZCONF_H */

File diff suppressed because it is too large Load diff