Created
January 19, 2015 13:56
-
-
Save kallisti5/86188b9fc6309ba085e7 to your computer and use it in GitHub Desktop.
benes-haiku patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/BeNES.rsrc b/BeNES.rsrc | |
deleted file mode 100644 | |
index 7fc19fe..0000000 | |
Binary files a/BeNES.rsrc and /dev/null differ | |
diff --git a/BeOS/BeFunctions.h b/BeOS/BeFunctions.h | |
deleted file mode 100644 | |
index fea0d26..0000000 | |
--- a/BeOS/BeFunctions.h | |
+++ /dev/null | |
@@ -1,9 +0,0 @@ | |
-#ifndef BEFUNCTIONS_H_DEFINED | |
-#define BEFUNCTIONS_H_DEFINED | |
- | |
-inline void BeShowMessage(char* msg) { | |
- BAlert* alert = new BAlert(NULL, msg, "OK"); | |
- alert->Go(); | |
-} | |
- | |
-#endif | |
diff --git a/BeOS/BeNES.cpp b/BeOS/BeNES.cpp | |
deleted file mode 100644 | |
index 42daf99..0000000 | |
--- a/BeOS/BeNES.cpp | |
+++ /dev/null | |
@@ -1,29 +0,0 @@ | |
-/* | |
-** BeNES - Nintendo Entertaiment System Emulator for BeOS | |
-** | |
-** * 1999 by makoto yamagata | |
-** | |
-** This program is free software; you can redistribute it and/or modify | |
-** it under the terms of the GNU General Public License as published by | |
-** the Free Software Foundation; either version 2 of the License, or | |
-** (at your option) any later version. | |
-** | |
-** This program is distributed in the hope that it will be useful, | |
-** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
-** GNU General Public License for more details. | |
-** | |
-** You should have received a copy of the GNU General Public License | |
-** along with this program; if not, write to the Free Software | |
-** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
-*/ | |
-#include "BeNESApp.h" | |
- | |
-int main(void) | |
-{ | |
- BeNESApp* app = new BeNESApp; | |
- | |
- app->Run(); | |
- | |
- return 0; | |
-} | |
diff --git a/BeOS/BeNESApp.cpp b/BeOS/BeNESApp.cpp | |
deleted file mode 100644 | |
index d6ba700..0000000 | |
--- a/BeOS/BeNESApp.cpp | |
+++ /dev/null | |
@@ -1,240 +0,0 @@ | |
-/* | |
-** BeNES - Nintendo Entertaiment System Emulator for BeOS | |
-** | |
-** * 1999 by makoto yamagata | |
-** | |
-** This program is free software; you can redistribute it and/or modify | |
-** it under the terms of the GNU General Public License as published by | |
-** the Free Software Foundation; either version 2 of the License, or | |
-** (at your option) any later version. | |
-** | |
-** This program is distributed in the hope that it will be useful, | |
-** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
-** GNU General Public License for more details. | |
-** | |
-** You should have received a copy of the GNU General Public License | |
-** along with this program; if not, write to the Free Software | |
-** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
-*/ | |
-#include <storage/FilePanel.h> | |
-#include <storage/Path.h> | |
-#include <interface/Alert.h> | |
-#include <interface/MenuItem.h> | |
-#include <stdio.h> | |
-#include "BeNESApp.h" | |
-#include "BeNESWin.h" | |
-#include "BeNESMsg.h" | |
-#include "BeNESJoypad.h" | |
-#include "NesException.h" | |
-#include "NesMainboard.h" | |
-#include "BeFunctions.h" | |
- | |
-#define INFO_FORM "\ | |
-BeNES Version 0.4.1\n\ | |
-\n\ | |
-Mapper: %02d\n\ | |
-PRG BANKS: %02ld\n\ | |
-CHR BANKS: %02ld\n\ | |
-MIRRORING: %s\n\ | |
-SAVERAM: %s\n\ | |
-TRAINER: %s" | |
- | |
-int32 BeNESApp::RunBeNES(void* arg) | |
-{ | |
- NesMainboard* obj = reinterpret_cast<NesMainboard*>(arg); | |
- obj->run(); | |
- return 0; | |
-} | |
- | |
-void BeNESApp::beginThread() | |
-{ | |
- mThread = spawn_thread(BeNESApp::RunBeNES, | |
- "BeNES", B_NORMAL_PRIORITY, &mMainboard); | |
- resume_thread(mThread); | |
-} | |
- | |
-void BeNESApp::endThread() | |
-{ | |
- if (mThread) { | |
- status_t result; | |
- mMainboard.stop(); | |
- wait_for_thread(mThread, &result); | |
- kill_thread(mThread); | |
- mThread = 0; | |
- } | |
-} | |
- | |
-void BeNESApp::ReadyToRun() | |
-{ | |
- mOpenPanel = new BFilePanel; | |
- mWindow = new BeNESWin; | |
- mJoypad = new BeNESJoypad; | |
- mOpenPanel->SetPanelDirectory("./"); | |
- mMainboard.connectDisplay(mWindow); | |
- mMainboard.connectJoypad(mJoypad); | |
- setSkipFrames(2); | |
- setFPS(60); | |
- setSound(true); | |
- setInput(2); | |
- mWindow->Show(); | |
-} | |
- | |
-void BeNESApp::RefsReceived(BMessage* msg) | |
-{ | |
- BMenuItem* infoItem = mWindow->getMenubar()->FindItem(BENES_INFO); | |
- infoItem->SetEnabled(false); | |
- | |
- entry_ref ref; | |
- msg->FindRef("refs", 0, &ref); | |
- | |
- BEntry entry(&ref); | |
- BPath path; | |
- entry.GetPath(&path); | |
- | |
- try { | |
- endThread(); | |
- mWindow->clear(); | |
- mROM.loadRomImage(path.Path()); | |
- infoItem->SetEnabled(true); | |
- mMainboard.insertROM(&mROM); | |
- beginThread(); | |
- } | |
- catch (std::bad_alloc& x) { | |
- BeShowMessage("cant alloc memory..."); | |
- } | |
- catch (Nes::FileOpenError& x) { | |
- BeShowMessage("cant open file..."); | |
- } | |
- catch (Nes::UnknownFormat& x) { | |
- BeShowMessage("unknown rom format..."); | |
- } | |
- catch (Nes::UnknownMapper& x) { | |
- char buff[256]; | |
- sprintf(buff, "unknown mapper = %d", x.mapper()); | |
- BeShowMessage(buff); | |
- } | |
- | |
-} | |
- | |
-bool BeNESApp::QuitRequested() | |
-{ | |
- endThread(); | |
- return true; | |
-} | |
- | |
-void BeNESApp::MessageReceived(BMessage* msg) | |
-{ | |
- switch (msg->what) { | |
- case BENES_OPEN: | |
- mOpenPanel->Show(); | |
- break; | |
- case BENES_INFO: | |
- showRomInfo(); | |
- break; | |
- case BENES_FRAMESKIP0: setSkipFrames(0); break; | |
- case BENES_FRAMESKIP1: setSkipFrames(1); break; | |
- case BENES_FRAMESKIP2: setSkipFrames(2); break; | |
- case BENES_FRAMESKIP3: setSkipFrames(3); break; | |
- case BENES_FRAMESKIP4: setSkipFrames(4); break; | |
- case BENES_FRAMES30: setFPS(30); break; | |
- case BENES_FRAMES40: setFPS(40); break; | |
- case BENES_FRAMES50: setFPS(50); break; | |
- case BENES_FRAMES60: setFPS(60); break; | |
- case BENES_FRAMESXX: setFPS(00); break; | |
- case BENES_ENABLESND: setSound(true); break; | |
- case BENES_DISABLESND: setSound(false); break; | |
- case BENES_INPUTJOYSTICK: setInput(0); break; | |
- case BENES_INPUTJOYPRO: setInput(1); break; | |
- case BENES_INPUTKEYBOARD: setInput(2); break; | |
- default: | |
- BApplication::MessageReceived(msg); | |
- break; | |
- } | |
-} | |
- | |
-void BeNESApp::showRomInfo() | |
-{ | |
- char buff[512]; | |
- sprintf(buff, INFO_FORM, | |
- mROM.getMapperNumber(), | |
- mROM.sizeofPRGBANKS(), | |
- mROM.sizeofCHRBANKS(), | |
- mROM.isVerticalMirror()? "VERTICAL": "HORIZONTAL", | |
- mROM.hasSaveRam()? "YES":"NO", | |
- mROM.hasTrainer()? "YES":"NO"); | |
- BeShowMessage(buff); | |
-} | |
- | |
-void BeNESApp::setSkipFrames(int skip) | |
-{ | |
- static uint32 cmdID[5] = { | |
- BENES_FRAMESKIP0, | |
- BENES_FRAMESKIP1, | |
- BENES_FRAMESKIP2, | |
- BENES_FRAMESKIP3, | |
- BENES_FRAMESKIP4, | |
- }; | |
- BMenu* menu = mWindow->getSkipFramesMenu(); | |
- BMenuItem* item = menu->FindMarked(); | |
- if (item) item->SetMarked(false); | |
- item = mWindow->getMenubar()->FindItem(cmdID[skip]); | |
- if (item) item->SetMarked(true); | |
- | |
- mMainboard.setSkipFrames(skip); | |
-} | |
- | |
-void BeNESApp::setFPS(int fps) | |
-{ | |
- BMenu* menu = mWindow->getFramesParSecMenu(); | |
- BMenuItem* item = menu->FindMarked(); | |
- if (item) item->SetMarked(false); | |
- int32 cmdID; | |
- switch (fps) { | |
- case 30: cmdID = BENES_FRAMES30; break; | |
- case 40: cmdID = BENES_FRAMES40; break; | |
- case 50: cmdID = BENES_FRAMES50; break; | |
- case 60: cmdID = BENES_FRAMES60; break; | |
- default: cmdID = BENES_FRAMESXX; break; | |
- } | |
- item = mWindow->getMenubar()->FindItem(cmdID); | |
- if (item) item->SetMarked(true); | |
- | |
- mWindow->setFPS(fps); | |
-} | |
- | |
-void BeNESApp::setSound(bool on) | |
-{ | |
- BMenu* menu = mWindow->getSoundMenu(); | |
- BMenuItem* item = menu->FindMarked(); | |
- if (item) item->SetMarked(false); | |
- int32 cmdID; | |
- if (on) { | |
- cmdID = BENES_ENABLESND; | |
- } | |
- else { | |
- cmdID = BENES_DISABLESND; | |
- } | |
- item = mWindow->getMenubar()->FindItem(cmdID); | |
- if (item) item->SetMarked(true); | |
- | |
- mMainboard.enableSound(on); | |
-} | |
- | |
-void BeNESApp::setInput(int type) | |
-{ | |
- BMenu* menu = mWindow->getInputMenu(); | |
- BMenuItem* item = menu->FindMarked(); | |
- if (item) item->SetMarked(false); | |
- int32 cmdID; | |
- switch (type) { | |
- case 0: cmdID = BENES_INPUTJOYSTICK; break; | |
- case 1: cmdID = BENES_INPUTJOYPRO; break; | |
- case 2: cmdID = BENES_INPUTKEYBOARD; break; | |
- default: cmdID = BENES_INPUTKEYBOARD; | |
- } | |
- item = mWindow->getMenubar()->FindItem(cmdID); | |
- if (item) item->SetMarked(true); | |
- | |
- mJoypad->setInput(type); | |
-} | |
diff --git a/BeOS/BeNESApp.h b/BeOS/BeNESApp.h | |
deleted file mode 100644 | |
index 6595545..0000000 | |
--- a/BeOS/BeNESApp.h | |
+++ /dev/null | |
@@ -1,66 +0,0 @@ | |
-/* | |
-** BeNES - Nintendo Entertaiment System Emulator for BeOS | |
-** | |
-** * 1999 by makoto yamagata | |
-** | |
-** This program is free software; you can redistribute it and/or modify | |
-** it under the terms of the GNU General Public License as published by | |
-** the Free Software Foundation; either version 2 of the License, or | |
-** (at your option) any later version. | |
-** | |
-** This program is distributed in the hope that it will be useful, | |
-** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
-** GNU General Public License for more details. | |
-** | |
-** You should have received a copy of the GNU General Public License | |
-** along with this program; if not, write to the Free Software | |
-** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
-*/ | |
-#ifndef BENESAPP_H_DEFINED | |
-#define BENESAPP_H_DEFINED | |
- | |
-#include <app/Application.h> | |
-#include <interface/MenuBar.h> | |
-#include "NesROM.h" | |
-#include "NesMainboard.h" | |
- | |
-class BeNESWin; | |
-class BeNESJoypad; | |
- | |
-class BeNESApp: public BApplication { | |
- thread_id mThread; | |
- BFilePanel* mOpenPanel; | |
- BeNESWin* mWindow; | |
- BeNESJoypad* mJoypad; | |
- NesROM mROM; | |
- NesMainboard mMainboard; | |
-public: | |
- | |
- BeNESApp(): | |
- BApplication("application/x-vnd.mkt-BeNES"), | |
- mThread(0), | |
- mOpenPanel(NULL), | |
- mWindow(NULL), | |
- mJoypad(NULL) { ; } | |
- ~BeNESApp() { | |
- endThread(); | |
- } | |
-private: | |
- // system | |
- void ReadyToRun(); | |
- void RefsReceived(BMessage* msg); | |
- void MessageReceived(BMessage* msg); | |
- bool QuitRequested(); | |
- // user | |
- void showRomInfo(); | |
- void beginThread(); | |
- void endThread(); | |
- static int32 RunBeNES(void* arg); | |
- void setSkipFrames(int skip); | |
- void setFPS(int fps); | |
- void setSound(bool on); | |
- void setInput(int type); | |
-}; | |
- | |
-#endif | |
diff --git a/BeOS/BeNESJoypad.cpp b/BeOS/BeNESJoypad.cpp | |
deleted file mode 100644 | |
index 44ef11d..0000000 | |
--- a/BeOS/BeNESJoypad.cpp | |
+++ /dev/null | |
@@ -1,200 +0,0 @@ | |
-#include "BeNESJoypad.h" | |
-#include <interface/InterfaceDefs.h> | |
-#include <device/Joystick.h> | |
- | |
-#include <stdio.h> | |
-#include <unistd.h> | |
- | |
-const char *PORTNAME="gameport/201"; | |
- | |
-inline bool isKeyDown(key_info& info, unsigned char key) | |
-{ | |
- return (info.key_states[key>>3] & (1<<(7-(key&7)))); | |
-} | |
- | |
-#define RETURN 0x47 | |
-#define SPACE 0x5e | |
-#define UP 0x57 | |
-#define DOWN 0x62 | |
-#define LEFT 0x61 | |
-#define RIGHT 0x63 | |
-#define LSHIFT 0x4b | |
-#define Z 0x4c | |
-#define X 0x4d | |
- | |
-#define PTOLERANCE 100 | |
-#define NTOLERANCE -100 | |
- | |
-BeNESJoypad::BeNESJoypad(): NesJoypad() | |
-{ | |
- mThread = spawn_thread(BeNESJoypad::Polling, | |
- "BeNESJoy", B_NORMAL_PRIORITY, this); | |
- resume_thread(mThread); | |
- inputType=2; | |
- mRunning = true; | |
-} | |
- | |
-BeNESJoypad::~BeNESJoypad() | |
-{ | |
- if (mThread) { | |
- status_t result; | |
- mRunning = false; | |
- wait_for_thread(mThread, &result); | |
- kill_thread(mThread); | |
- } | |
-} | |
- | |
-void BeNESJoypad::setInput(int type) | |
-{ | |
- inputType = type; | |
-} | |
- | |
-int32 BeNESJoypad::Polling(void* arg) | |
-{ | |
- const int pollingRate = 1000000 / 60; | |
- BJoystick bjoy; | |
- status_t st; | |
- int32 buttonstat; | |
- int16 axesstat[2]; | |
- BeNESJoypad* joy = reinterpret_cast<BeNESJoypad*>(arg); | |
- key_info info; | |
- int type; | |
- | |
- st = bjoy.Open(PORTNAME); | |
- | |
- while (joy->mRunning) | |
- { | |
- snooze(pollingRate); | |
- type = joy->inputType; | |
- | |
- if (type==2) | |
- { | |
- get_key_info(&info); | |
- | |
- if (isKeyDown(info, Z)) joy->pushA(); | |
- else joy->releaseA(); | |
- | |
- if (isKeyDown(info, X) || isKeyDown(info, LSHIFT)) joy->pushB(); | |
- else joy->releaseB(); | |
- | |
- if (isKeyDown(info, RETURN)) joy->pushStart(); | |
- else joy->releaseStart(); | |
- | |
- if (isKeyDown(info, SPACE)) joy->pushSelect(); | |
- else joy->releaseSelect(); | |
- | |
- if (isKeyDown(info, UP)) joy->pushUp(); | |
- else joy->releaseUp(); | |
- | |
- if (isKeyDown(info, DOWN)) joy->pushDown(); | |
- else joy->releaseDown(); | |
- | |
- if (isKeyDown(info, LEFT)) joy->pushLeft(); | |
- else joy->releaseLeft(); | |
- | |
- if (isKeyDown(info, RIGHT)) joy->pushRight(); | |
- else joy->releaseRight(); | |
- } | |
- else if(type==1) | |
- { | |
- joy->releaseA(); | |
- joy->releaseB(); | |
- joy->releaseSelect(); | |
- joy->releaseStart(); | |
- joy->releaseUp(); | |
- joy->releaseDown(); | |
- joy->releaseLeft(); | |
- joy->releaseRight(); | |
- | |
- bjoy.Update(); | |
- buttonstat = bjoy.ButtonValues(); | |
- bjoy.GetAxisValues(axesstat); | |
- | |
- if (buttonstat) | |
- { | |
- if ((buttonstat & 8)==8) joy->pushA(); | |
- | |
- if((buttonstat & 16) == 16) joy->pushB(); | |
- | |
- if((buttonstat & 256) == 256) joy->pushStart(); | |
- | |
- if ((buttonstat & 512) == 512) joy->pushSelect(); | |
- } | |
- if (*(axesstat+1)) | |
- { | |
- if (*(axesstat+1) > 0) | |
- { | |
- joy->pushUp(); | |
- } | |
- else if (*(axesstat+1) < 0) | |
- { | |
- joy->pushDown(); | |
- } | |
- } | |
- | |
- if (*(axesstat)) | |
- { | |
- if (*(axesstat) > 0) | |
- { | |
- joy->pushRight(); | |
- } | |
- else if (*(axesstat) < 0) | |
- { | |
- joy->pushLeft(); | |
- } | |
- } | |
- } | |
- else if(type==0) | |
- { | |
- joy->releaseA(); | |
- joy->releaseB(); | |
- joy->releaseSelect(); | |
- joy->releaseStart(); | |
- joy->releaseUp(); | |
- joy->releaseDown(); | |
- joy->releaseLeft(); | |
- joy->releaseRight(); | |
- | |
- bjoy.Update(); | |
- buttonstat = bjoy.ButtonValues(); | |
- bjoy.GetAxisValues(axesstat); | |
- | |
- if (buttonstat) | |
- { | |
- if ((buttonstat & 2)==2) joy->pushA(); | |
- | |
- if((buttonstat & 1) == 1) joy->pushB(); | |
- | |
- if((buttonstat & 4) == 4) joy->pushStart(); | |
- | |
- if ((buttonstat & 8) == 8) joy->pushSelect(); | |
- } | |
- if (*(axesstat+1)) | |
- { | |
- if (*(axesstat+1) > PTOLERANCE) | |
- { | |
- joy->pushDown(); | |
- } | |
- else if (*(axesstat+1) < NTOLERANCE) | |
- { | |
- joy->pushUp(); | |
- } | |
- } | |
- | |
- if (*(axesstat)) | |
- { | |
- if (*(axesstat) > 0) | |
- { | |
- joy->pushRight(); | |
- } | |
- else if (*(axesstat) < 0) | |
- { | |
- joy->pushLeft(); | |
- } | |
- } | |
- } | |
- | |
- | |
- } | |
- return 0; | |
-} | |
diff --git a/BeOS/BeNESJoypad.h b/BeOS/BeNESJoypad.h | |
deleted file mode 100644 | |
index 4bd740b..0000000 | |
--- a/BeOS/BeNESJoypad.h | |
+++ /dev/null | |
@@ -1,18 +0,0 @@ | |
-#ifndef BENESJOYPAD_H_DEFINED | |
-#define BENESJOYPAD_H_DEFINED | |
- | |
-#include "NesJoypad.h" | |
-#include <be/kernel/OS.h> | |
- | |
-class BeNESJoypad: public NesJoypad { | |
- thread_id mThread; | |
- bool mRunning; | |
- int inputType; | |
-public: | |
- BeNESJoypad(); | |
- ~BeNESJoypad(); | |
- static int32 Polling(void* arg); | |
- void setInput(int type); | |
-}; | |
- | |
-#endif | |
diff --git a/BeOS/BeNESMenu.cpp b/BeOS/BeNESMenu.cpp | |
deleted file mode 100644 | |
index eb4fb86..0000000 | |
--- a/BeOS/BeNESMenu.cpp | |
+++ /dev/null | |
@@ -1,121 +0,0 @@ | |
-/* | |
-** BeNES - Nintendo Entertaiment System Emulator for BeOS | |
-** | |
-** * 1999 by makoto yamagata | |
-** | |
-** This program is free software; you can redistribute it and/or modify | |
-** it under the terms of the GNU General Public License as published by | |
-** the Free Software Foundation; either version 2 of the License, or | |
-** (at your option) any later version. | |
-** | |
-** This program is distributed in the hope that it will be useful, | |
-** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
-** GNU General Public License for more details. | |
-** | |
-** You should have received a copy of the GNU General Public License | |
-** along with this program; if not, write to the Free Software | |
-** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
-*/ | |
-#include <app/Application.h> | |
-#include <interface/MenuItem.h> | |
-#include "BeNESMenu.h" | |
-#include "BeNESMsg.h" | |
- | |
-const string BeNESMenu::File = "File"; | |
-const string BeNESMenu::Setting = "Setting"; | |
-const string BeNESMenu::FrameSkip = "Skip Frames"; | |
-const string BeNESMenu::FramesParSec = "Frames Par Sec."; | |
-const string BeNESMenu::Sound = "Sound"; | |
-const string BeNESMenu::Input = "Input"; | |
- | |
-BMenu* BeNESMenu::buildFileMenu() | |
-{ | |
- // Build File Menu | |
- BMenu* menu = new BMenu(File.c_str()); | |
- BMenuItem* item = NULL; | |
- item = new BMenuItem("Open...", new BMessage(BENES_OPEN), 'O'); | |
- menu->AddItem(item); | |
- menu->AddSeparatorItem(); | |
- item = new BMenuItem("ROM Info...", new BMessage(BENES_INFO), 'I'); | |
- item->SetEnabled(false); | |
- menu->AddItem(item); | |
- menu->AddSeparatorItem(); | |
- item = new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED), 'Q'); | |
- menu->AddItem(item); | |
- | |
- menu->SetTargetForItems(be_app); | |
- | |
- return menu; | |
-} | |
- | |
-BMenu* BeNESMenu::buildSettingMenu() | |
-{ | |
- BMenuItem* item = NULL; | |
- | |
- // Build FrameSkip SubMenu | |
- BMenu* skip = new BMenu(FrameSkip.c_str()); | |
- item = new BMenuItem("0", new BMessage(BENES_FRAMESKIP0)); | |
- skip->AddItem(item); | |
- item = new BMenuItem("1", new BMessage(BENES_FRAMESKIP1)); | |
- skip->AddItem(item); | |
- item = new BMenuItem("2", new BMessage(BENES_FRAMESKIP2)); | |
- skip->AddItem(item); | |
- item = new BMenuItem("3", new BMessage(BENES_FRAMESKIP3)); | |
- skip->AddItem(item); | |
- item = new BMenuItem("4", new BMessage(BENES_FRAMESKIP4)); | |
- skip->AddItem(item); | |
- skip->SetTargetForItems(be_app); | |
- | |
- // Build Frames par sec SubMenu | |
- BMenu* fps = new BMenu(FramesParSec.c_str()); | |
- item = new BMenuItem("30", new BMessage(BENES_FRAMES30)); | |
- fps->AddItem(item); | |
- item = new BMenuItem("40", new BMessage(BENES_FRAMES40)); | |
- fps->AddItem(item); | |
- item = new BMenuItem("50", new BMessage(BENES_FRAMES50)); | |
- fps->AddItem(item); | |
- item = new BMenuItem("60", new BMessage(BENES_FRAMES60)); | |
- fps->AddItem(item); | |
- item = new BMenuItem("MAX", new BMessage(BENES_FRAMESXX)); | |
- fps->AddItem(item); | |
- fps->SetTargetForItems(be_app); | |
- | |
- // Build Sound SubMenu | |
- BMenu* snd = new BMenu(Sound.c_str()); | |
- item = new BMenuItem("Enable", new BMessage(BENES_ENABLESND)); | |
- snd->AddItem(item); | |
- item = new BMenuItem("Disable", new BMessage(BENES_DISABLESND)); | |
- snd->AddItem(item); | |
- snd->SetTargetForItems(be_app); | |
- | |
- //Build Input Menu | |
- BMenu* inp = new BMenu(Input.c_str()); | |
- item = new BMenuItem("Joystick", new BMessage(BENES_INPUTJOYSTICK)); | |
- inp->AddItem(item); | |
- item = new BMenuItem("Gamepad Pro", new BMessage(BENES_INPUTJOYPRO)); | |
- inp->AddItem(item); | |
- item = new BMenuItem("Keyboard", new BMessage(BENES_INPUTKEYBOARD)); | |
- inp->AddItem(item); | |
- inp->SetTargetForItems(be_app); | |
- | |
- // Build Setting Menu | |
- BMenu* menu = new BMenu(Setting.c_str()); | |
- menu->AddItem(skip); | |
- menu->AddItem(fps); | |
- menu->AddItem(snd); | |
- menu->AddItem(inp); | |
- menu->SetTargetForItems(be_app); | |
- | |
- return menu; | |
-} | |
- | |
-BMenuBar* BeNESMenu::Build() | |
-{ | |
- BMenuBar* bar = new BMenuBar(BRect(), B_EMPTY_STRING); | |
- // File Menu | |
- bar->AddItem(buildFileMenu()); | |
- // Setting Menu | |
- bar->AddItem(buildSettingMenu()); | |
- return bar; | |
-} | |
diff --git a/BeOS/BeNESMenu.h b/BeOS/BeNESMenu.h | |
deleted file mode 100644 | |
index ae62476..0000000 | |
--- a/BeOS/BeNESMenu.h | |
+++ /dev/null | |
@@ -1,41 +0,0 @@ | |
-/* | |
-** BeNES - Nintendo Entertaiment System Emulator for BeOS | |
-** | |
-** * 1999 by makoto yamagata | |
-** | |
-** This program is free software; you can redistribute it and/or modify | |
-** it under the terms of the GNU General Public License as published by | |
-** the Free Software Foundation; either version 2 of the License, or | |
-** (at your option) any later version. | |
-** | |
-** This program is distributed in the hope that it will be useful, | |
-** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
-** GNU General Public License for more details. | |
-** | |
-** You should have received a copy of the GNU General Public License | |
-** along with this program; if not, write to the Free Software | |
-** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
-*/ | |
-#ifndef BENESMENU_H_DEFINED | |
-#define BENESMENU_H_DEFINED | |
- | |
-#include <interface/MenuBar.h> | |
-#include <string> | |
- | |
-class BeNESMenu { | |
- BeNESMenu() {}; | |
-public: | |
- static const string File; | |
- static const string Setting; | |
- static const string FrameSkip; | |
- static const string FramesParSec; | |
- static const string Sound; | |
- static const string Input; | |
- static BMenuBar* Build(); | |
-private: | |
- static BMenu* buildFileMenu(); | |
- static BMenu* buildSettingMenu(); | |
-}; | |
- | |
-#endif | |
diff --git a/BeOS/BeNESMenuBuilder.h b/BeOS/BeNESMenuBuilder.h | |
deleted file mode 100644 | |
index 7406f2d..0000000 | |
--- a/BeOS/BeNESMenuBuilder.h | |
+++ /dev/null | |
@@ -1,34 +0,0 @@ | |
-/* | |
-** BeNES - Nintendo Entertaiment System Emulator for BeOS | |
-** | |
-** * 1999 by makoto yamagata | |
-** | |
-** This program is free software; you can redistribute it and/or modify | |
-** it under the terms of the GNU General Public License as published by | |
-** the Free Software Foundation; either version 2 of the License, or | |
-** (at your option) any later version. | |
-** | |
-** This program is distributed in the hope that it will be useful, | |
-** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
-** GNU General Public License for more details. | |
-** | |
-** You should have received a copy of the GNU General Public License | |
-** along with this program; if not, write to the Free Software | |
-** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
-*/ | |
-#ifndef BENESMENUBUILDER_H_DEFINED | |
-#define BENESMENUBUILDER_H_DEFINED | |
- | |
-#include <interface/MenuBar.h> | |
- | |
-class BeNESMenu { | |
- BeNESMenu() {}; | |
-public: | |
- static BMenuBar* Build(); | |
-private: | |
- static BMenu* buildFileMenu(); | |
- static BMenu* buildSettingMenu(); | |
-}; | |
- | |
-#endif | |
diff --git a/BeOS/BeNESMsg.h b/BeOS/BeNESMsg.h | |
deleted file mode 100644 | |
index d48cd16..0000000 | |
--- a/BeOS/BeNESMsg.h | |
+++ /dev/null | |
@@ -1,27 +0,0 @@ | |
-#ifndef BENESMSG_H_DEFINED | |
-#define BENESMSG_H_DEFINED | |
- | |
-const uint32 BENES_OPEN = 'OpeN'; | |
-const uint32 BENES_INFO = 'InfO'; | |
- | |
-const uint32 BENES_FRAMESKIP0 = 'SKP0'; | |
-const uint32 BENES_FRAMESKIP1 = 'SKP1'; | |
-const uint32 BENES_FRAMESKIP2 = 'SKP2'; | |
-const uint32 BENES_FRAMESKIP3 = 'SKP3'; | |
-const uint32 BENES_FRAMESKIP4 = 'SKP4'; | |
- | |
-const uint32 BENES_FRAMES30 = 'FPS3'; | |
-const uint32 BENES_FRAMES40 = 'FPS4'; | |
-const uint32 BENES_FRAMES50 = 'FPS5'; | |
-const uint32 BENES_FRAMES60 = 'FPS6'; | |
-const uint32 BENES_FRAMESXX = 'FPSX'; | |
- | |
-const uint32 BENES_ENABLESND = 'ESND'; | |
-const uint32 BENES_DISABLESND = 'DSND'; | |
- | |
-const uint32 BENES_INPUTJOYSTICK = 'JSTK'; | |
-const uint32 BENES_INPUTJOYPRO = 'JPRO'; | |
-const uint32 BENES_INPUTKEYBOARD = 'KEYB'; | |
- | |
- | |
-#endif | |
diff --git a/BeOS/BeNESPalette.h b/BeOS/BeNESPalette.h | |
deleted file mode 100644 | |
index 62b9671..0000000 | |
--- a/BeOS/BeNESPalette.h | |
+++ /dev/null | |
@@ -1,41 +0,0 @@ | |
-#ifndef BENESPALETTE_H_DEFINED | |
-#define BENESPALETTE_H_DEFINED | |
- | |
-#include <interface/GraphicsDefs.h> | |
- | |
-rgb_color BeNESPalette[64] = { | |
- { 0x7f,0x7f,0x7f,0xff }, { 0x00,0x00,0xff,0xff }, | |
- { 0x00,0x00,0xbf,0xff }, { 0x47,0x2b,0xbf,0xff }, | |
- { 0x97,0x00,0x87,0xff }, { 0xab,0x00,0x23,0xff }, | |
- { 0xab,0x13,0x00,0xff }, { 0x8b,0x17,0x00,0xff }, | |
- { 0x53,0x30,0x00,0xff }, { 0x00,0x78,0x00,0xff }, | |
- { 0x00,0x6b,0x00,0xff }, { 0x00,0x5b,0x00,0xff }, | |
- { 0x00,0x43,0x58,0xff }, { 0x00,0x00,0x00,0xff }, | |
- { 0x00,0x00,0x00,0xff }, { 0x00,0x00,0x00,0xff }, | |
- { 0xbf,0xbf,0xbf,0xff }, { 0x00,0x78,0xF8,0xff }, | |
- { 0x00,0x58,0xf8,0xff }, { 0x6b,0x47,0xff,0xff }, | |
- { 0xdb,0x00,0xcd,0xff }, { 0xe7,0x00,0x5b,0xff }, | |
- { 0xf8,0x38,0x00,0xff }, { 0xe7,0x5f,0x13,0xff }, | |
- { 0xaf,0x7f,0x00,0xff }, { 0x00,0xb8,0x00,0xff }, | |
- { 0x00,0xab,0x00,0xff }, { 0x00,0xab,0x47,0xff }, | |
- { 0x00,0x8b,0x8b,0xff }, { 0x00,0x00,0x00,0xff }, | |
- { 0x00,0x00,0x00,0xff }, { 0x00,0x00,0x00,0xff }, | |
- { 0xf8,0xf8,0xf8,0xff }, { 0x3f,0xbf,0xff,0xff }, | |
- { 0x6b,0x88,0xff,0xff }, { 0x98,0x78,0xf8,0xff }, | |
- { 0xf8,0x78,0xf8,0xff }, { 0xf8,0x58,0x98,0xff }, | |
- { 0xf8,0x78,0x58,0xff }, { 0xff,0xa3,0x47,0xff }, | |
- { 0xf8,0xb8,0x00,0xff }, { 0xb8,0xf8,0x18,0xff }, | |
- { 0x5b,0xdb,0x57,0xff }, { 0x58,0xf8,0x98,0xff }, | |
- { 0x00,0xeb,0xdb,0xff }, { 0x78,0x78,0x78,0xff }, | |
- { 0x00,0x00,0x00,0xff }, { 0x00,0x00,0x00,0xff }, | |
- { 0xff,0xff,0xff,0xff }, { 0xa7,0xe7,0xff,0xff }, | |
- { 0xb8,0xb8,0xf8,0xff }, { 0xd8,0xb8,0xf8,0xff }, | |
- { 0xf8,0xb8,0xf8,0xff }, { 0xfb,0xa7,0xc3,0xff }, | |
- { 0xf0,0xd0,0xb0,0xff }, { 0xff,0xe3,0xab,0xff }, | |
- { 0xfb,0xdb,0x7b,0xff }, { 0xd8,0xf8,0x78,0xff }, | |
- { 0xb8,0xf8,0xb8,0xff }, { 0xb8,0xf8,0xd8,0xff }, | |
- { 0x00,0xff,0xff,0xff }, { 0xf8,0xd8,0xf8,0xff }, | |
- { 0x00,0x00,0x00,0xff }, { 0x00,0x00,0x00,0xff }, | |
-}; | |
- | |
-#endif | |
diff --git a/BeOS/BeNESWin.cpp b/BeOS/BeNESWin.cpp | |
deleted file mode 100644 | |
index b93048e..0000000 | |
--- a/BeOS/BeNESWin.cpp | |
+++ /dev/null | |
@@ -1,141 +0,0 @@ | |
-/* | |
-** BeNES - Nintendo Entertaiment System Emulator for BeOS | |
-** | |
-** * 1999 by makoto yamagata | |
-** | |
-** This program is free software; you can redistribute it and/or modify | |
-** it under the terms of the GNU General Public License as published by | |
-** the Free Software Foundation; either version 2 of the License, or | |
-** (at your option) any later version. | |
-** | |
-** This program is distributed in the hope that it will be useful, | |
-** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
-** GNU General Public License for more details. | |
-** | |
-** You should have received a copy of the GNU General Public License | |
-** along with this program; if not, write to the Free Software | |
-** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
-*/ | |
-#include <app/Application.h> | |
-#include <app/Message.h> | |
-#include <interface/Screen.h> | |
-#include <string> | |
-#include "BeNESPalette.h" | |
-#include "BeNESWin.h" | |
-#include "BeNESMenu.h" | |
- | |
-#define RETURN 0x47 | |
-#define SPACE 0x5e | |
-#define UP 0x57 | |
-#define DOWN 0x62 | |
-#define LEFT 0x61 | |
-#define RIGHT 0x63 | |
-#define Z 0x4c | |
-#define X 0x4d | |
- | |
-//-------------------------------------------------------------------------- | |
-BeNESWin::BeNESWin(): | |
- BWindow(BRect(X, Y, X+W, Y+H), | |
- "BeNES", | |
- B_TITLED_WINDOW, | |
- B_NOT_RESIZABLE), | |
- mOffscreen(NULL), | |
- mView(NULL), | |
- mMenubar(NULL), | |
- mFrameSnooze(0) | |
-{ | |
- Lock(); | |
- mMenubar = BeNESMenu::Build(); | |
- AddChild(mMenubar); | |
- BRect barFrame(mMenubar->Frame()); | |
- | |
- ResizeTo(W, H+barFrame.Height()); | |
- | |
- mView = new BView(BRect(0, 0, W, H), NULL, B_FOLLOW_ALL, 0); | |
- AddChild(mView); | |
- mView->MoveBy(0, barFrame.Height()+1); | |
- mView->SetViewColor(0, 0, 0); | |
- | |
- mOffscreen = new BBitmap(BRect(0, 0, W-1, H-1), B_COLOR_8_BIT); | |
- mBits = static_cast<uchar*>(mOffscreen->Bits()); | |
- mBytesPerRow = mOffscreen->BytesPerRow(); | |
- BScreen* screen = new BScreen(this); | |
- memset(mBits, screen->IndexForColor(0, 0, 0, 255), W*H); | |
- for (int i=0; i<64; i++) { | |
- IndexPalette[i] = screen->IndexForColor(BeNESPalette[i]); | |
- } | |
- delete screen; | |
- Unlock(); | |
-} | |
- | |
-//-------------------------------------------------------------------------- | |
-BMenu* BeNESWin::getSkipFramesMenu() | |
-{ | |
- BMenu* menu = mMenubar->SubmenuAt(1)->SubmenuAt(0); | |
- return menu; | |
-} | |
- | |
-//-------------------------------------------------------------------------- | |
-BMenu* BeNESWin::getFramesParSecMenu() | |
-{ | |
- BMenu* menu = mMenubar->SubmenuAt(1)->SubmenuAt(1); | |
- return menu; | |
-} | |
- | |
-//-------------------------------------------------------------------------- | |
-BMenu* BeNESWin::getSoundMenu() | |
-{ | |
- BMenu* menu = mMenubar->SubmenuAt(1)->SubmenuAt(2); | |
- return menu; | |
-} | |
- | |
-//-------------------------------------------------------------------------- | |
-BMenu* BeNESWin::getInputMenu() | |
-{ | |
- BMenu* menu = mMenubar->SubmenuAt(1)->SubmenuAt(3); | |
- return menu; | |
-} | |
- | |
-//-------------------------------------------------------------------------- | |
-void BeNESWin::setFPS(int fps) | |
-{ | |
- if (fps) { | |
- mFrameSnooze = 1000000 / fps; | |
- } | |
- else { | |
- mFrameSnooze = 0; | |
- } | |
-} | |
- | |
-//-------------------------------------------------------------------------- | |
-bool BeNESWin::QuitRequested() | |
-{ | |
- be_app->PostMessage(B_QUIT_REQUESTED, be_app); | |
- return true; | |
-} | |
- | |
-//-------------------------------------------------------------------------- | |
-void BeNESWin::updateScreen(const NesVirtualScreen* screen, bool draw) | |
-{ | |
- static bigtime_t prevTime = 0; | |
- if (draw) { | |
- static const int Y_MIN = NesDisplay::VisibleTop; | |
- static const int Y_MAX = NesDisplay::VisibleBottom; | |
- | |
- for (int y=Y_MIN; y<=Y_MAX; y++) { | |
- for (int x=8; x<256-8; x++) { | |
- *(mBits+(y*mBytesPerRow)+x) = | |
- IndexPalette[screen->bits[y][x]]; | |
- } | |
- } | |
- Lock(); | |
- mView->DrawBitmap(mOffscreen); | |
- Unlock(); | |
- } | |
- bigtime_t snooze_time = mFrameSnooze - (system_time()-prevTime); | |
- if (snooze_time > 0) { | |
- snooze(snooze_time); | |
- } | |
- prevTime = system_time(); | |
-} | |
diff --git a/BeOS/BeNESWin.h b/BeOS/BeNESWin.h | |
deleted file mode 100644 | |
index 121178b..0000000 | |
--- a/BeOS/BeNESWin.h | |
+++ /dev/null | |
@@ -1,51 +0,0 @@ | |
-/* | |
-** BeNES - Nintendo Entertaiment System Emulator for BeOS | |
-** | |
-** * 1999 by makoto yamagata | |
-** | |
-** This program is free software; you can redistribute it and/or modify | |
-** it under the terms of the GNU General Public License as published by | |
-** the Free Software Foundation; either version 2 of the License, or | |
-** (at your option) any later version. | |
-** | |
-** This program is distributed in the hope that it will be useful, | |
-** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
-** GNU General Public License for more details. | |
-** | |
-** You should have received a copy of the GNU General Public License | |
-** along with this program; if not, write to the Free Software | |
-** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
-*/ | |
-#ifndef BENESWIN_H_DEFINED | |
-#define BENESWIN_H_DEFINED | |
- | |
-#include <interface/Window.h> | |
-#include <interface/Bitmap.h> | |
-#include "NesDisplay.h" | |
-#include "NesJoypad.h" | |
- | |
-class BeNESWin: public BWindow, | |
- public NesDisplay { | |
- BBitmap* mOffscreen; | |
- BView* mView; | |
- uint32 IndexPalette[256]; | |
- enum { X=100, Y=100, W=256, H=240 }; | |
- uchar* mBits; | |
- int mBytesPerRow; | |
- BMenuBar* mMenubar; | |
- bigtime_t mFrameSnooze; | |
-public: | |
- BeNESWin(); | |
- bool QuitRequested(); | |
- BMenuBar* getMenubar() { return mMenubar; } | |
- BMenu* getSkipFramesMenu(); | |
- BMenu* getFramesParSecMenu(); | |
- BMenu* getSoundMenu(); | |
- BMenu* getInputMenu(); | |
- void updateScreen(const NesVirtualScreen* screen, bool draw); | |
- void setFPS(int fps); | |
- void clear() { Lock(); mView->Invalidate(); Unlock(); } | |
-}; | |
- | |
-#endif | |
diff --git a/Mappers/NesMapper1.h b/Mappers/NesMapper1.h | |
index 8bfa6cd..0149712 100644 | |
--- a/Mappers/NesMapper1.h | |
+++ b/Mappers/NesMapper1.h | |
@@ -21,7 +21,7 @@ | |
#define NESMAPPER1_H_DEFINED | |
#include "NesAbstructMapper.h" | |
-#include <string> | |
+#include <cstring> | |
class NesMapper1: public NesAbstructMapper { | |
uchar mRegs[4]; | |
diff --git a/NES/FileException.h b/NES/FileException.h | |
index e701949..d82630a 100644 | |
--- a/NES/FileException.h | |
+++ b/NES/FileException.h | |
@@ -3,6 +3,8 @@ | |
#include <stdexcept> | |
+using std::string; | |
+ | |
class FileOpenError: public std::runtime_error { | |
public: | |
FileOpenError(const string what_arg=""): | |
diff --git a/NES/NesCPU.h b/NES/NesCPU.h | |
index 99d3379..8d8746d 100644 | |
--- a/NES/NesCPU.h | |
+++ b/NES/NesCPU.h | |
@@ -29,6 +29,8 @@ extern "C" { | |
#include "NesPPURegisters.h" | |
#include "NesCPUInterface.h" | |
+#include <cstring> | |
+ | |
class NesIO; | |
class NesCPU: public NesCPUInterface { | |
diff --git a/NES/NesIO.h b/NES/NesIO.h | |
index 7394152..f260343 100644 | |
--- a/NES/NesIO.h | |
+++ b/NES/NesIO.h | |
@@ -125,4 +125,4 @@ public: | |
virtual NesPPUInterface* getPPU() { return mPPU; } | |
virtual NesROMInterface* getROM() { return mROM; } | |
}; | |
-#endif; | |
+#endif | |
diff --git a/NES/NesPPU.cpp b/NES/NesPPU.cpp | |
index 9569fcd..f5cd81c 100644 | |
--- a/NES/NesPPU.cpp | |
+++ b/NES/NesPPU.cpp | |
@@ -1,7 +1,8 @@ | |
/* | |
-** BeNES - Nintendo Entertaiment System Emulator for BeOS | |
+** WeeNES - Nintendo Entertaiment System Emulator for Haiku | |
** | |
-** * 1999 by makoto yamagata | |
+** * 2010 Alexander von Gluck (WeeNES) | |
+** * 1999 by makoto yamagata (BeNES) | |
** | |
** This program is free software; you can redistribute it and/or modify | |
** it under the terms of the GNU General Public License as published by | |
@@ -42,6 +43,10 @@ const int EXECUTE_NMI_LINE = 245; | |
const int VBLANK_LINE = 243; | |
const int DRAWBEGIN_LINE = 8; | |
+// NES resolution | |
+const int WIDTH = 256; | |
+const int HEIGHT = 240; | |
+ | |
//---------------------------------------------------------------- | |
void NesPPU::init() | |
{ | |
@@ -57,18 +62,18 @@ void NesPPU::renderLine(int scanline) | |
uchar v_scroll = mBackgroundScroll.getVScrollValue(); | |
uchar h_scroll = mBackgroundScroll.getHScrollValue(); | |
int top = scanline + v_scroll; | |
- if (top >= 240) { | |
- top -= 240; | |
+ if (top >= HEIGHT) { | |
+ top -= HEIGHT; | |
nametbl_base ^= 0x0800; | |
} | |
int y = scanline; | |
int x = 0; | |
int width = 8 - (h_scroll & 0x07); | |
bool firstBankChange = true; | |
- while (x < 256) { | |
+ while (x < WIDTH) { | |
int left = x + h_scroll; | |
- if (left >= 256) { | |
- left -= 256; | |
+ if (left >= WIDTH) { | |
+ left -= WIDTH; | |
if (firstBankChange) { | |
nametbl_base ^= 0x0400; | |
firstBankChange = false; | |
@@ -90,7 +95,7 @@ void NesPPU::renderLine(int scanline) | |
tileA >>= 1; | |
tileB >>= 1; | |
int pos_x = x + ((width-1)-j); | |
- if (pos_x >= 256) continue; | |
+ if (pos_x >= WIDTH) continue; | |
mScreenMask.bits[y][pos_x] = color_index; | |
color_index = mPPURam[0x3F00+color_index]; | |
mVirtualScreen.bits[y][pos_x] = color_index; | |
@@ -133,12 +138,12 @@ void NesPPU::putSprite(int scanline) | |
int x = cell[i].x; | |
if (cell[i].isHorizontalFlip()) x += (j); | |
else x += (7-j); | |
- if ((x>=256) || (x<0)) continue; | |
+ if ((x>=WIDTH) || (x<0)) continue; | |
int y = cell[i].y+1; | |
if (cell[i].isVerticalFlip()) y += ((spriteHeight-1)-line); | |
else y += line; | |
- if ((y>=240) || (y<0)) continue; | |
+ if ((y>=HEIGHT) || (y<0)) continue; | |
color_index = color_hi|color_index; | |
if (cell[i].isBackgroundFront() && (mScreenMask.bits[y][x]&~0x80)) { | |
@@ -201,7 +206,7 @@ int NesPPU::scanLine(NesCPUInterface* cpu) | |
if ((getScanline()==mSpriteHitLine) && mControlB.isSpriteVisible()) { | |
mStatus.setSpriteHitBit(true); | |
} | |
- if ((getScanline()>=DRAWBEGIN_LINE) && (getScanline()<240)) { | |
+ if ((getScanline()>=DRAWBEGIN_LINE) && (getScanline()<HEIGHT)) { | |
if (mFrameCounter == 0) { | |
if (mControlB.isBgVisible()) { | |
renderLine(getScanline()); | |
diff --git a/NES/NesPPU.h b/NES/NesPPU.h | |
index 12ac880..8801469 100644 | |
--- a/NES/NesPPU.h | |
+++ b/NES/NesPPU.h | |
@@ -52,7 +52,7 @@ private: | |
int spriteHit0y(); | |
-private: friend NesIO;//Access from NesIO Class Only | |
+private: friend class NesIO;//Access from NesIO Class Only | |
void init(); | |
int scanLine(NesCPUInterface* cpu); | |
diff --git a/NES/NesPPUImpl.h b/NES/NesPPUImpl.h | |
index 3f1fd12..4a28057 100644 | |
--- a/NES/NesPPUImpl.h | |
+++ b/NES/NesPPUImpl.h | |
@@ -25,6 +25,8 @@ | |
#include "NesPPUInterface.h" | |
#include "NesPPURam.h" | |
+#include <cstring> | |
+ | |
const int PPU_SCANLINE_PAR_FRAME = 262; | |
class NesPPUImpl: public NesPPUInterface { | |
diff --git a/NES/NesPPURam.h b/NES/NesPPURam.h | |
index 777e0b9..85ce2a6 100644 | |
--- a/NES/NesPPURam.h | |
+++ b/NES/NesPPURam.h | |
@@ -22,6 +22,7 @@ | |
#include "NesTypes.h" | |
#include <string> | |
+#include <cstring> | |
class NesPPURam { | |
uchar mPatternTable[0x2000]; | |
diff --git a/NES/NesROM.cpp b/NES/NesROM.cpp | |
index 2638bb1..1a51595 100644 | |
--- a/NES/NesROM.cpp | |
+++ b/NES/NesROM.cpp | |
@@ -25,6 +25,12 @@ | |
#include "NesMapperFactory.h" | |
#include <memory> | |
+#include <iostream> | |
+#include <fstream> | |
+#include <sstream> | |
+ | |
+using namespace std; | |
+ | |
//------------------------------------------------------------------------ | |
void NesROM::loadRomImage(const char* name) | |
{ | |
diff --git a/NES/NesROM.h b/NES/NesROM.h | |
index 83b39b7..3587587 100644 | |
--- a/NES/NesROM.h | |
+++ b/NES/NesROM.h | |
@@ -1,6 +1,7 @@ | |
/* | |
** BeNES - Nintendo Entertaiment System Emulator for BeOS | |
** | |
+** * 2010 Alexander von Gluck | |
** * 1999 by makoto yamagata | |
** | |
** This program is free software; you can redistribute it and/or modify | |
@@ -23,8 +24,13 @@ | |
#ifndef NESROM_H_DEFINED | |
#define NESROM_H_DEFINED | |
+#include <iostream> | |
#include <fstream> | |
#include <string> | |
+#include <cstring> | |
+ | |
+using std::string; | |
+ | |
#include "NesTypes.h" | |
#include "NesAbstructMapper.h" | |
#include "NesROMInterface.h" | |
@@ -117,10 +123,10 @@ public: | |
return mTrainer; | |
} | |
private: | |
- uchar* readTrainer(ifstream& ifs); | |
- uchar* readPrgrom(ifstream& ifs, int* prg_size); | |
- uchar* readChrrom(ifstream& ifs, int* chr_size); | |
+ uchar* readTrainer(std::ifstream& ifs); | |
+ uchar* readPrgrom(std::ifstream& ifs, int* prg_size); | |
+ uchar* readChrrom(std::ifstream& ifs, int* chr_size); | |
uchar* readSaveRam(const char* name); | |
}; | |
-#endif; | |
+#endif | |
diff --git a/README b/README | |
new file mode 100644 | |
index 0000000..91273d7 | |
--- /dev/null | |
+++ b/README | |
@@ -0,0 +1,31 @@ | |
+===================================== | |
+ | |
+ WeeNES - NES emulator for Haiku | |
+ | |
+ Based largely on BeNES the FAMICOM EMULATOR for BeOS | |
+ originally by makoto yamagata(mkt@kk.iij4u.or.jp). | |
+ | |
+ Mushroom icon based on artwork of Frédéric Bellaiche | |
+ | |
+===================================== | |
+ | |
+ 2010 Alexander von Gluck, http://unixzen.com | |
+ | |
+ | |
+Keyboard controls | |
+---------------------------------------------------------- | |
+Enter: Start | |
+Space: Select | |
+Z: A | |
+X: B | |
+Up: Up | |
+Down: Down | |
+Left: Left | |
+Right: Right | |
+ | |
+ | |
+ | |
+Compiling | |
+===================================== | |
+Requirement: http://dev.haiku-os.org/ticket/5375 | |
+Requirement: gcc2 or gcc4 environment | |
diff --git a/Read.me b/Read.me | |
deleted file mode 100644 | |
index 2e60c87..0000000 | |
--- a/Read.me | |
+++ /dev/null | |
@@ -1,161 +0,0 @@ | |
-================================================ | |
- BeNES FAMICOM EMULATOR for BeOS | |
- by makoto yamagata(mkt@kk.iij4u.or.jp) | |
-================================================ | |
- | |
- | |
- | |
-================================================ | |
-1。はじめに | |
-================================================ | |
- | |
-BeNESをダウンロードして頂きありがとうございます。 | |
- | |
-私が、初めに目標としていたエミュレータは、「初代スーパーマリオが動作する」 | |
-という単純なものでした。 | |
-もちろん、サウンドサポートもありません。純粋にエミュレーション技術に興味が | |
-あって、どのようなものかを試してみたかったのです。 | |
-時期を同じくして、私はBeOSにも興味を持っていました。 | |
-エミュレーション技術と、BeOS。 | |
-この二つの事柄に興味を示した時期が偶然一致し、BeNESが生まれました。 | |
- | |
-これは、私の初めてのBeWareとなります。 | |
-そして同時に、私の中で深く記憶に残るBeWareとなりそうです。 | |
- | |
-================================================ | |
-2。メニュー | |
-================================================ | |
- | |
-●「File」メニュー | |
- | |
-「Open...」項目 | |
-ファイルダイアログが開きますので、実行したいROMイメージを指定してください。 | |
-読込みが完了しエミュレーションが開始されます。 | |
-なお、サポートされているROMフォーマットは★iNESフォーマットのみ★です。 | |
- | |
-「Info...」項目 | |
-現在読込まれているROMイメージについての情報を表示します。 | |
-各フィールドの意味は以下の通りです。 | |
-Mapper: マッパー番号 | |
-PRG BANKS: プログラムROMバンクサイズ | |
-CHR BANKS: キャラクターROMバンクサイズ | |
-MIRRORING: ミラーリングの種類 | |
-SAVERAM: セーブラムの有無 | |
-TRAINER: トレイナー(パッチ)の有無 | |
- | |
-「Quit」項目 | |
-エミュレーションを修了し、アプリケーションを閉じます。 | |
- | |
-●「Setting」メニュー | |
- | |
-「Skip Frames」項目 | |
-フレームスキップの設定をします。 | |
-ゲームが早い/遅い場合に使用します。 | |
-5段階です。 | |
- | |
-「Frames Par Sec」項目 | |
-1秒間に描画するフレーム数を設定します。 | |
-ただし、現状は、完璧ではありません。 | |
- | |
-「Sound」項目 | |
-サウンドのEnable/Disableを制御します。 | |
-Enableでサウンドが有効になります。 | |
- | |
-=============================================== | |
-3。操作方法 | |
-================================================ | |
- | |
-現在はキーボードからの操作のみサポートしています。 | |
-ファミコンのコントローラとキーボードの対応は以下の通りです。 | |
- | |
-スタートボタン:エンターキー | |
-セレクトボタン:スペースバー | |
-Aボタン:Zキー | |
-Bボタン:Xキー/左シフトキー | |
-上ボタン:上カーソル | |
-下ボタン:下カーソル | |
-右ボタン:右カーソル | |
-左ボタン:左カーソル | |
- | |
-================================================ | |
-4。サポートマッパー | |
-================================================ | |
-#0/#1/#2/#3/#4/#7 | |
- | |
-================================================ | |
-5。FAQ | |
-================================================ | |
- | |
-Q:BeNESはなんて読むのですか? | |
-A:「びーねす」と発音してください。 | |
- | |
-Q:キーアサインを変更したいのですが? | |
-A:キーアサインは、BeNESJoypad.cpp内の該当ルーチンを書き換える事により変更できます。 | |
- | |
-Q:ゲームスピードが遅い/早いのですが? | |
-A:フレームスキップメニューにより、フレームスキップレートを変更できます。 | |
-また、FPS(Frame Par Sec.)も設定できますので、調整してみてください。 | |
-さらに微妙な速度変更が必要な時は、BeNESWin.cpp内の該当ルーチンを書き換えてください。 | |
- | |
-Q:サウンドが鳴らないのですが? | |
-A:SettingsメニューのSound項目はEnableになっていますか? | |
-A:サウンドをサポートしましたが、稀に正常に初期化できていないケースがあるようです。 | |
-BeOS上で、適当なサウンドファイルを再生してから実行してみてください。 | |
- | |
- | |
-Q:コントローラBは使えますか? | |
-A:BeNESはコントローラBをサポートしていません。 | |
- | |
-Q:サポートされているMapperのROMが動作しないのですが? | |
-A:ROMイメージは正常ですか? | |
-Internet上のROMは特定のEmulator向けにpatchがあたっている場合があります。 | |
-オリジナルのROMイメージを使ってみてください。 | |
-それでも動作しない場合は、BeNESのバグです(笑) | |
-メールにて報告していただければ、善処したいと思います。 | |
- | |
-Q:FAMフォーマットは使えますか? | |
-A:BeNESでは、iNESフォーマットのみの対応となっています。 | |
- | |
-Q:Famtasia等のsavファイルは使えますか? | |
-A:おそらく使えるんじゃないかと思われます(笑) | |
-自信無しです。 | |
-つかえた/つかえない等、報告を頂けると幸いです。 | |
-savファイルはROMイメージと同じディレクトリに置いてください。 | |
- | |
-================================================ | |
-6。Special Thanks! | |
-================================================ | |
- | |
-順不同 | |
- | |
-Marat氏 | |
-M6502 CPUコアを利用させていただきました。 | |
-また、氏のNES DocumentはBeNESを開発するにあたり大変参考になりました。 | |
- | |
-NORI氏/taka2氏: | |
-NESのアーキテクチャに関する助言をいただきました。 | |
- | |
-bero氏: | |
-ホームページにて有用なNESの日本語の資料を公開されてます。 | |
-彼のページ無くしては、BeNESは作成できなかったでしょう。 | |
-また、BeNESのCPUコアは氏が修正/変更したものをベースにしています。 | |
- | |
-goroh氏: | |
-ホームページにて有用なMapper情報を公開されてます。 | |
-Mapper#4は氏の資料があったからこそ、サポートが実現しました。 | |
-また、NESのアーキテクチャに関して有用な助言をいただきました。 | |
- | |
-Nyef氏: | |
-DarcNESの著者である氏にもNESのエミュレーションに関して助言をいただきました。 | |
-また、DarcNESのソースコードもBeNESを作成するにあたって、大変参考になりました。 | |
- | |
-besom氏/影の協力者T氏 | |
-BeNESの再現性に関してメールにて御報告いただきました。 | |
- | |
-Ki氏 | |
-この方なくしては、BeNESのサウンドサポートは実現しなかったと言っても過言ではないでしょう。 | |
-サウンドサポートに関して、多くのアドバイス、時には激励を頂きました。 | |
-サウンドプログラミングに関して、まったく知識のなかった私に、とても丁寧に分かりやすく説明 | |
-してくれました。 | |
- | |
-ありがとうございました。 | |
diff --git a/SEAL/NesSound.cpp b/SEAL/NesSound.cpp | |
index 41168ec..8e8b620 100644 | |
--- a/SEAL/NesSound.cpp | |
+++ b/SEAL/NesSound.cpp | |
@@ -1,284 +1,285 @@ | |
-#include <be/media/SoundPlayer.h> | |
-#include "NesSound.h" | |
-#include "WaveCreator.h" | |
- | |
-unsigned short SQ0_882Hz[50] = { | |
- 0x3636, 0x574B, 0x4EB4, 0x52D4, 0x4E11, 0x5666, 0x21EB, 0xEC27, | |
- 0xF33E, 0xF0A4, 0xF12A, 0xF194, 0xF0DD, 0xF13D, 0xF12A, 0xF121, | |
- 0xF183, 0xF14A, 0xF174, 0xF1DE, 0xF17C, 0xF1B9, 0xF203, 0xF19E, | |
- 0xF208, 0xF21A, 0xF1D9, 0xF25A, 0xF231, 0xF214, 0xF28C, 0xF24F, | |
- 0xF253, 0xF294, 0xF261, 0xF263, 0xF281, 0xF27B, 0xF29B, 0xF2B2, | |
- 0xF2A3, 0xF2C6, 0xF2CD, 0xF2CC, 0xF2F2, 0xF3BF, 0xF2AB, 0xF3FF, | |
- 0xF3BF, 0xF10B | |
-}; | |
- | |
-unsigned short SQ1_882Hz[50] = { | |
- 0x3984, 0x47B3, 0x41F5, 0x450C, 0x42CA, 0x436F, 0x4325, 0x4207, | |
- 0x420B, 0x4217, 0x3F16, 0x46F3, 0x1357, 0xDE89, 0xE582, 0xE30B, | |
- 0xE39C, 0xE420, 0xE36F, 0xE3CB, 0xE3C5, 0xE3EA, 0xE42B, 0xE42D, | |
- 0xE44D, 0xE49B, 0xE484, 0xE4C5, 0xE4EC, 0xE4E2, 0xE4E6, 0xE510, | |
- 0xE516, 0xE555, 0xE561, 0xE574, 0xE5A2, 0xE5BB, 0xE5CA, 0xE60F, | |
- 0xE607, 0xE61F, 0xE650, 0xE64F, 0xE68D, 0xE79B, 0xE5BA, 0xE93F, | |
- 0xE44F, 0xEED7 | |
-}; | |
- | |
-unsigned short SQ2_882Hz[50] = { | |
- 0x2DCF, 0x30C1, 0x2E8E, 0x302F, 0x2EB1, 0x2F3A, 0x2EF9, 0x2EDD, | |
- 0x2E91, 0x2E33, 0x2E06, 0x2DAF, 0x2D89, 0x2D50, 0x2D05, 0x2CD5, | |
- 0x2CA4, 0x2C50, 0x2C46, 0x2BC5, 0x2ACC, 0x2C98, 0x2809, 0x3050, | |
- 0x160B, 0xD1FA, 0xCD1D, 0xD017, 0xCDE0, 0xCFBC, 0xCF1C, 0xCF30, | |
- 0xCF7A, 0xCFBA, 0xCFE8, 0xD04A, 0xD06C, 0xD0A7, 0xD0FD, 0xD11B, | |
- 0xD163, 0xD1AD, 0xD1C7, 0xD207, 0xD26A, 0xD34B, 0xD1B4, 0xD610, | |
- 0xCE0A, 0xE64B | |
-}; | |
- | |
-unsigned short SQ3_882Hz[50] = { | |
- 0x17E8, 0x1819, 0x16EF, 0x1866, 0x1715, 0x17C6, 0x17B1, 0x179F, | |
- 0x175B, 0x175C, 0x172A, 0x170F, 0x1700, 0x16CE, 0x16A5, 0x16A1, | |
- 0x1666, 0x166D, 0x1656, 0x1619, 0x15F3, 0x15E2, 0x15B9, 0x15C4, | |
- 0x159D, 0x1578, 0x1570, 0x154A, 0x1532, 0x152F, 0x14EA, 0x14EE, | |
- 0x1405, 0x14FA, 0x13A8, 0x1423, 0x15BA, 0xD77C, 0xB373, 0xBC2E, | |
- 0xB8A9, 0xBA5A, 0xBA6D, 0xBA82, 0xBAED, 0xBC01, 0xBA9D, 0xBF03, | |
- 0xB6E5, 0xD378 | |
-}; | |
- | |
-unsigned short TRI_882Hz[50] = { | |
- 0x01D3, 0x07D9, 0x0E0A, 0x140C, 0x19BA, 0x1FA3, 0x2527, 0x2ACC, | |
- 0x309C, 0x35AE, 0x3AB6, 0x4041, 0x44BF, 0x45B5, 0x4423, 0x3E03, | |
- 0x387D, 0x32C2, 0x2CC8, 0x271B, 0x20D8, 0x1AC5, 0x1511, 0x0EB8, | |
- 0x0887, 0x0291, 0xFC15, 0xF5CC, 0xEFA2, 0xE909, 0xE2C7, 0xDC83, | |
- 0xD575, 0xCF01, 0xC88E, 0xC1B5, 0xBB7D, 0xB41F, 0xB15F, 0xB326, | |
- 0xB9A8, 0xC159, 0xC898, 0xCF73, 0xD69E, 0xDE00, 0xE496, 0xEB55, | |
- 0xF207, 0xF845 | |
-}; | |
- | |
-const double SOUND_CONST = 111860.78 / 882 * 44100; | |
-const double NOISE_CONST = (44100.0 * 13); | |
-const int M_BITS = 13; | |
-const int NOISE_BUFSIZE = (1<<M_BITS); | |
- | |
-unsigned short NOISE[NOISE_BUFSIZE]; | |
- | |
-const int WAVE_LENGTH = 100; | |
-const WORD AUDIO_FORMAT = | |
- AUDIO_FORMAT_16BITS|AUDIO_FORMAT_MONO|AUDIO_FORMAT_LOOP; | |
- | |
-//====================================================================== | |
-inline void createSound( | |
- NesSoundVoice& sound, unsigned short* data, int len) | |
-{ | |
- sound.mWave = WaveCreator::Audio16BitMono( | |
- 44100, reinterpret_cast<LPBYTE>(data), len); | |
- sound.mWave->wFormat |= AUDIO_FORMAT; | |
- sound.mWave->dwLoopStart = 0L; | |
- sound.mWave->dwLoopEnd = sound.mWave->dwLength; | |
- ACreateAudioVoice(&(sound.mVoice)); | |
- ASetVoicePanning(sound.mVoice, 128); | |
-} | |
- | |
-inline void destroySound(NesSoundVoice& sound) | |
-{ | |
- AStopVoice(sound.mVoice); | |
- ADestroyAudioVoice(sound.mVoice); | |
- AFreeWaveFile(sound.mWave); | |
-} | |
- | |
-inline void createNoise(unsigned short *buf, const int bits, int size) | |
-{ | |
- static int m=0x0011; | |
- int i, xor; | |
- | |
- for( i=0; i<size>>1; i++ ){ | |
- xor = m & 1; | |
- m >>= 1; | |
- xor ^= m & 1; | |
- m |= xor<<(bits-1); | |
- if( m & (1<<(bits-1)) ) /* if MSB = 1 */ | |
- buf[i] = (short)(-m); | |
- else | |
- buf[i] = (short)m; | |
- } | |
-} | |
- | |
-//---------------------------------------------------------------------- | |
-NesSound::NesSound(): mEnabled(0) | |
-{ | |
- static unsigned short* sq_waves[4] = { | |
- SQ0_882Hz, SQ1_882Hz, SQ2_882Hz, SQ3_882Hz, | |
- }; | |
- // initialize & open audio | |
- AUDIOINFO info; | |
- AInitialize(); | |
- info.nDeviceId = AUDIO_DEVICE_MAPPER; | |
- info.wFormat = AUDIO_FORMAT_16BITS | AUDIO_FORMAT_MONO; | |
- info.nSampleRate = 44100; | |
- AOpenAudio(&info); | |
- // regist voices | |
- AOpenVoices(NUMSOUNDS); | |
- // Create SQ Sound | |
- for (int i=0; i<4; i++) { | |
- createSound(mSq0Sound[i], sq_waves[i], WAVE_LENGTH); | |
- createSound(mSq1Sound[i], sq_waves[i], WAVE_LENGTH); | |
- } | |
- // Create Tri Sound | |
- createSound(mTriSound, TRI_882Hz, WAVE_LENGTH); | |
- // Create Niz Sound | |
- createNoise(NOISE, M_BITS, sizeof(NOISE)); | |
- createSound(mNizSound, NOISE, sizeof(NOISE)); | |
- | |
- mChannel[0].mSound = &mSq0Sound[0]; | |
- mChannel[1].mSound = &mSq1Sound[0]; | |
- mChannel[2].mSound = &mTriSound; | |
- mChannel[3].mSound = &mNizSound; | |
-} | |
- | |
-//---------------------------------------------------------------------- | |
-NesSound::~NesSound() | |
-{ | |
- // Free SQ Sound | |
- for (int i=0; i<4; i++) { | |
- destroySound(mSq0Sound[i]); | |
- destroySound(mSq1Sound[i]); | |
- } | |
- // Free Tri Sound | |
- destroySound(mTriSound); | |
- // Free Niz Sound | |
- destroySound(mNizSound); | |
- | |
- ACloseVoices(); | |
- // close audio | |
- ACloseAudio(); | |
-} | |
- | |
-//---------------------------------------------------------------------- | |
-void NesSound::setVolume(int channel, long val) | |
-{ | |
- mChannel[channel].mVolume = val; | |
-} | |
- | |
-//---------------------------------------------------------------------- | |
-void NesSound::setFreq(int channel, unsigned short val) | |
-{ | |
- long freq = static_cast<long>(SOUND_CONST / (val+1)); | |
- mChannel[channel].mFreqValue = freq; | |
- mChannel[channel].mFreq = val; | |
-} | |
- | |
-//---------------------------------------------------------------------- | |
-void NesSound::setNoiseFreq(unsigned short val) | |
-{ | |
- long freq = static_cast<long>((NOISE_CONST/val)); | |
- mChannel[3].mFreqValue = freq; | |
- mChannel[3].mFreq = val; | |
-} | |
- | |
-//---------------------------------------------------------------------- | |
-void NesSound::play(int channel) | |
-{ | |
- NesSoundSource* current = &mChannel[channel]; | |
- if (mEnabled & (0x01<<channel)) { | |
- if (channel == 3) { | |
- ASetVoicePosition(current->mSound->mVoice, 0); | |
- } | |
- APrimeVoice(current->mSound->mVoice, current->mSound->mWave); | |
- ASetVoiceFrequency(current->mSound->mVoice, current->mFreqValue); | |
- ASetVoiceVolume(current->mSound->mVoice, current->mVolume); | |
- AStartVoice(current->mSound->mVoice); | |
- current->mPlaying = true; | |
- } | |
-} | |
- | |
-//---------------------------------------------------------------------- | |
-void NesSound::update(int channel) | |
-{ | |
- NesSoundSource* current = &mChannel[channel]; | |
- if (mEnabled & (0x01<<channel)) { | |
- if (channel == 3) { | |
- ASetVoicePosition(current->mSound->mVoice, 0); | |
- } | |
- if (current->mChanged) { | |
- AStopVoice(current->mSound->mVoice); | |
- current->mSound = current->mChanged; | |
- current->mChanged = NULL; | |
- APrimeVoice(current->mSound->mVoice, current->mSound->mWave); | |
- ASetVoiceFrequency(current->mSound->mVoice, current->mFreqValue); | |
- ASetVoiceVolume(current->mSound->mVoice, current->mVolume); | |
- AStartVoice(current->mSound->mVoice); | |
- } | |
- else { | |
- ASetVoiceFrequency(current->mSound->mVoice, current->mFreqValue); | |
- ASetVoiceVolume(current->mSound->mVoice, current->mVolume); | |
- } | |
- } | |
-} | |
- | |
-//---------------------------------------------------------------------- | |
-void NesSound::stop(int channel) | |
-{ | |
- NesSoundSource* current = &mChannel[channel]; | |
- current->mPlaying = false; | |
- ASetVoiceVolume(current->mSound->mVoice, 0); | |
- AStopVoice(current->mSound->mVoice); | |
-} | |
- | |
-//---------------------------------------------------------------------- | |
-void NesSound::enableChannel(unsigned char enabled) | |
-{ | |
- mEnabled = enabled; | |
- for (int i=0; i<NUMCHANNELS; i++) { | |
- if (!(mEnabled & (0x01<<i))) { | |
- stop(i); | |
- } | |
- } | |
-} | |
- | |
-//---------------------------------------------------------------------- | |
-void NesSound::setSq0Wave(unsigned char type) | |
-{ | |
- NesSoundSource* current = &mChannel[0]; | |
- if (current->mSound != &mSq0Sound[type&0x03]) { | |
- current->mChanged = &mSq0Sound[type&0x03]; | |
- } | |
-} | |
- | |
-//---------------------------------------------------------------------- | |
-void NesSound::setSq1Wave(unsigned char type) | |
-{ | |
- NesSoundSource* current = &mChannel[1]; | |
- if (current->mSound != &mSq1Sound[type&0x03]) { | |
- current->mChanged = &mSq1Sound[type&0x03]; | |
- } | |
-} | |
- | |
-//====================================================================== | |
-//#define TEST | |
-#ifdef TEST | |
-int main() | |
-{ | |
- NesSound sound; | |
- unsigned char a4015; | |
- unsigned char a4000 = 0x3f; | |
- unsigned char a4001 = 0x00; | |
- unsigned char a4002 = 0x7e; | |
- unsigned char a4003 = 0x00; | |
- | |
- // 4015 write | |
- a4015 = 0x01; | |
- sound.enableChannel(a4015); | |
- | |
- // 4003 write | |
- sound.setSquareWaveType(0, (a4000>>6)&0x03); | |
- unsigned short val = ((a4003&0x07)<<8)|a4002; | |
- val = static_cast<short>(111860.78 / (val+1)); | |
- sound.play(0, 441); | |
- | |
- getchar(); | |
- | |
- // 4015 write | |
- a4015 = 0; | |
- sound.enableChannel(a4015); | |
- | |
- return 0; | |
-} | |
-#endif | |
- | |
+#include <be/media/SoundPlayer.h> | |
+#include "NesSound.h" | |
+#include "WaveCreator.h" | |
+ | |
+unsigned short SQ0_882Hz[50] = { | |
+ 0x3636, 0x574B, 0x4EB4, 0x52D4, 0x4E11, 0x5666, 0x21EB, 0xEC27, | |
+ 0xF33E, 0xF0A4, 0xF12A, 0xF194, 0xF0DD, 0xF13D, 0xF12A, 0xF121, | |
+ 0xF183, 0xF14A, 0xF174, 0xF1DE, 0xF17C, 0xF1B9, 0xF203, 0xF19E, | |
+ 0xF208, 0xF21A, 0xF1D9, 0xF25A, 0xF231, 0xF214, 0xF28C, 0xF24F, | |
+ 0xF253, 0xF294, 0xF261, 0xF263, 0xF281, 0xF27B, 0xF29B, 0xF2B2, | |
+ 0xF2A3, 0xF2C6, 0xF2CD, 0xF2CC, 0xF2F2, 0xF3BF, 0xF2AB, 0xF3FF, | |
+ 0xF3BF, 0xF10B | |
+}; | |
+ | |
+unsigned short SQ1_882Hz[50] = { | |
+ 0x3984, 0x47B3, 0x41F5, 0x450C, 0x42CA, 0x436F, 0x4325, 0x4207, | |
+ 0x420B, 0x4217, 0x3F16, 0x46F3, 0x1357, 0xDE89, 0xE582, 0xE30B, | |
+ 0xE39C, 0xE420, 0xE36F, 0xE3CB, 0xE3C5, 0xE3EA, 0xE42B, 0xE42D, | |
+ 0xE44D, 0xE49B, 0xE484, 0xE4C5, 0xE4EC, 0xE4E2, 0xE4E6, 0xE510, | |
+ 0xE516, 0xE555, 0xE561, 0xE574, 0xE5A2, 0xE5BB, 0xE5CA, 0xE60F, | |
+ 0xE607, 0xE61F, 0xE650, 0xE64F, 0xE68D, 0xE79B, 0xE5BA, 0xE93F, | |
+ 0xE44F, 0xEED7 | |
+}; | |
+ | |
+unsigned short SQ2_882Hz[50] = { | |
+ 0x2DCF, 0x30C1, 0x2E8E, 0x302F, 0x2EB1, 0x2F3A, 0x2EF9, 0x2EDD, | |
+ 0x2E91, 0x2E33, 0x2E06, 0x2DAF, 0x2D89, 0x2D50, 0x2D05, 0x2CD5, | |
+ 0x2CA4, 0x2C50, 0x2C46, 0x2BC5, 0x2ACC, 0x2C98, 0x2809, 0x3050, | |
+ 0x160B, 0xD1FA, 0xCD1D, 0xD017, 0xCDE0, 0xCFBC, 0xCF1C, 0xCF30, | |
+ 0xCF7A, 0xCFBA, 0xCFE8, 0xD04A, 0xD06C, 0xD0A7, 0xD0FD, 0xD11B, | |
+ 0xD163, 0xD1AD, 0xD1C7, 0xD207, 0xD26A, 0xD34B, 0xD1B4, 0xD610, | |
+ 0xCE0A, 0xE64B | |
+}; | |
+ | |
+unsigned short SQ3_882Hz[50] = { | |
+ 0x17E8, 0x1819, 0x16EF, 0x1866, 0x1715, 0x17C6, 0x17B1, 0x179F, | |
+ 0x175B, 0x175C, 0x172A, 0x170F, 0x1700, 0x16CE, 0x16A5, 0x16A1, | |
+ 0x1666, 0x166D, 0x1656, 0x1619, 0x15F3, 0x15E2, 0x15B9, 0x15C4, | |
+ 0x159D, 0x1578, 0x1570, 0x154A, 0x1532, 0x152F, 0x14EA, 0x14EE, | |
+ 0x1405, 0x14FA, 0x13A8, 0x1423, 0x15BA, 0xD77C, 0xB373, 0xBC2E, | |
+ 0xB8A9, 0xBA5A, 0xBA6D, 0xBA82, 0xBAED, 0xBC01, 0xBA9D, 0xBF03, | |
+ 0xB6E5, 0xD378 | |
+}; | |
+ | |
+unsigned short TRI_882Hz[50] = { | |
+ 0x01D3, 0x07D9, 0x0E0A, 0x140C, 0x19BA, 0x1FA3, 0x2527, 0x2ACC, | |
+ 0x309C, 0x35AE, 0x3AB6, 0x4041, 0x44BF, 0x45B5, 0x4423, 0x3E03, | |
+ 0x387D, 0x32C2, 0x2CC8, 0x271B, 0x20D8, 0x1AC5, 0x1511, 0x0EB8, | |
+ 0x0887, 0x0291, 0xFC15, 0xF5CC, 0xEFA2, 0xE909, 0xE2C7, 0xDC83, | |
+ 0xD575, 0xCF01, 0xC88E, 0xC1B5, 0xBB7D, 0xB41F, 0xB15F, 0xB326, | |
+ 0xB9A8, 0xC159, 0xC898, 0xCF73, 0xD69E, 0xDE00, 0xE496, 0xEB55, | |
+ 0xF207, 0xF845 | |
+}; | |
+ | |
+const double SOUND_CONST = 111860.78 / 882 * 44100; | |
+const double NOISE_CONST = (44100.0 * 13); | |
+const int M_BITS = 13; | |
+const int NOISE_BUFSIZE = (1<<M_BITS); | |
+ | |
+unsigned short NOISE[NOISE_BUFSIZE]; | |
+ | |
+const int WAVE_LENGTH = 100; | |
+const WORD AUDIO_FORMAT = | |
+ AUDIO_FORMAT_16BITS|AUDIO_FORMAT_MONO|AUDIO_FORMAT_LOOP; | |
+ | |
+//====================================================================== | |
+inline void createSound( | |
+ NesSoundVoice& sound, unsigned short* data, int len) | |
+{ | |
+ sound.mWave = WaveCreator::Audio16BitMono( | |
+ 44100, reinterpret_cast<LPBYTE>(data), len); | |
+ sound.mWave->wFormat |= AUDIO_FORMAT; | |
+ sound.mWave->dwLoopStart = 0L; | |
+ sound.mWave->dwLoopEnd = sound.mWave->dwLength; | |
+ ACreateAudioVoice(&(sound.mVoice)); | |
+ ASetVoicePanning(sound.mVoice, 128); | |
+} | |
+ | |
+inline void destroySound(NesSoundVoice& sound) | |
+{ | |
+ AStopVoice(sound.mVoice); | |
+ ADestroyAudioVoice(sound.mVoice); | |
+ AFreeWaveFile(sound.mWave); | |
+} | |
+ | |
+inline void createNoise(unsigned short *buf, const int bits, int size) | |
+{ | |
+ static int m=0x0011; | |
+ int i; | |
+ int XOR; | |
+ | |
+ for( i=0; i<size>>1; i++ ){ | |
+ XOR = m & 1; | |
+ m >>= 1; | |
+ XOR ^= m & 1; | |
+ m |= XOR<<(bits-1); | |
+ if( m & (1<<(bits-1)) ) /* if MSB = 1 */ | |
+ buf[i] = (short)(-m); | |
+ else | |
+ buf[i] = (short)m; | |
+ } | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+NesSound::NesSound(): mEnabled(0) | |
+{ | |
+ static unsigned short* sq_waves[4] = { | |
+ SQ0_882Hz, SQ1_882Hz, SQ2_882Hz, SQ3_882Hz, | |
+ }; | |
+ // initialize & open audio | |
+ AUDIOINFO info; | |
+ AInitialize(); | |
+ info.nDeviceId = AUDIO_DEVICE_MAPPER; | |
+ info.wFormat = AUDIO_FORMAT_16BITS | AUDIO_FORMAT_MONO; | |
+ info.nSampleRate = 44100; | |
+ AOpenAudio(&info); | |
+ // regist voices | |
+ AOpenVoices(NUMSOUNDS); | |
+ // Create SQ Sound | |
+ for (int i=0; i<4; i++) { | |
+ createSound(mSq0Sound[i], sq_waves[i], WAVE_LENGTH); | |
+ createSound(mSq1Sound[i], sq_waves[i], WAVE_LENGTH); | |
+ } | |
+ // Create Tri Sound | |
+ createSound(mTriSound, TRI_882Hz, WAVE_LENGTH); | |
+ // Create Niz Sound | |
+ createNoise(NOISE, M_BITS, sizeof(NOISE)); | |
+ createSound(mNizSound, NOISE, sizeof(NOISE)); | |
+ | |
+ mChannel[0].mSound = &mSq0Sound[0]; | |
+ mChannel[1].mSound = &mSq1Sound[0]; | |
+ mChannel[2].mSound = &mTriSound; | |
+ mChannel[3].mSound = &mNizSound; | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+NesSound::~NesSound() | |
+{ | |
+ // Free SQ Sound | |
+ for (int i=0; i<4; i++) { | |
+ destroySound(mSq0Sound[i]); | |
+ destroySound(mSq1Sound[i]); | |
+ } | |
+ // Free Tri Sound | |
+ destroySound(mTriSound); | |
+ // Free Niz Sound | |
+ destroySound(mNizSound); | |
+ | |
+ ACloseVoices(); | |
+ // close audio | |
+ ACloseAudio(); | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+void NesSound::setVolume(int channel, long val) | |
+{ | |
+ mChannel[channel].mVolume = val; | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+void NesSound::setFreq(int channel, unsigned short val) | |
+{ | |
+ long freq = static_cast<long>(SOUND_CONST / (val+1)); | |
+ mChannel[channel].mFreqValue = freq; | |
+ mChannel[channel].mFreq = val; | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+void NesSound::setNoiseFreq(unsigned short val) | |
+{ | |
+ long freq = static_cast<long>((NOISE_CONST/val)); | |
+ mChannel[3].mFreqValue = freq; | |
+ mChannel[3].mFreq = val; | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+void NesSound::play(int channel) | |
+{ | |
+ NesSoundSource* current = &mChannel[channel]; | |
+ if (mEnabled & (0x01<<channel)) { | |
+ if (channel == 3) { | |
+ ASetVoicePosition(current->mSound->mVoice, 0); | |
+ } | |
+ APrimeVoice(current->mSound->mVoice, current->mSound->mWave); | |
+ ASetVoiceFrequency(current->mSound->mVoice, current->mFreqValue); | |
+ ASetVoiceVolume(current->mSound->mVoice, current->mVolume); | |
+ AStartVoice(current->mSound->mVoice); | |
+ current->mPlaying = true; | |
+ } | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+void NesSound::update(int channel) | |
+{ | |
+ NesSoundSource* current = &mChannel[channel]; | |
+ if (mEnabled & (0x01<<channel)) { | |
+ if (channel == 3) { | |
+ ASetVoicePosition(current->mSound->mVoice, 0); | |
+ } | |
+ if (current->mChanged) { | |
+ AStopVoice(current->mSound->mVoice); | |
+ current->mSound = current->mChanged; | |
+ current->mChanged = NULL; | |
+ APrimeVoice(current->mSound->mVoice, current->mSound->mWave); | |
+ ASetVoiceFrequency(current->mSound->mVoice, current->mFreqValue); | |
+ ASetVoiceVolume(current->mSound->mVoice, current->mVolume); | |
+ AStartVoice(current->mSound->mVoice); | |
+ } | |
+ else { | |
+ ASetVoiceFrequency(current->mSound->mVoice, current->mFreqValue); | |
+ ASetVoiceVolume(current->mSound->mVoice, current->mVolume); | |
+ } | |
+ } | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+void NesSound::stop(int channel) | |
+{ | |
+ NesSoundSource* current = &mChannel[channel]; | |
+ current->mPlaying = false; | |
+ ASetVoiceVolume(current->mSound->mVoice, 0); | |
+ AStopVoice(current->mSound->mVoice); | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+void NesSound::enableChannel(unsigned char enabled) | |
+{ | |
+ mEnabled = enabled; | |
+ for (int i=0; i<NUMCHANNELS; i++) { | |
+ if (!(mEnabled & (0x01<<i))) { | |
+ stop(i); | |
+ } | |
+ } | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+void NesSound::setSq0Wave(unsigned char type) | |
+{ | |
+ NesSoundSource* current = &mChannel[0]; | |
+ if (current->mSound != &mSq0Sound[type&0x03]) { | |
+ current->mChanged = &mSq0Sound[type&0x03]; | |
+ } | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+void NesSound::setSq1Wave(unsigned char type) | |
+{ | |
+ NesSoundSource* current = &mChannel[1]; | |
+ if (current->mSound != &mSq1Sound[type&0x03]) { | |
+ current->mChanged = &mSq1Sound[type&0x03]; | |
+ } | |
+} | |
+ | |
+//====================================================================== | |
+//#define TEST | |
+#ifdef TEST | |
+int main() | |
+{ | |
+ NesSound sound; | |
+ unsigned char a4015; | |
+ unsigned char a4000 = 0x3f; | |
+ unsigned char a4001 = 0x00; | |
+ unsigned char a4002 = 0x7e; | |
+ unsigned char a4003 = 0x00; | |
+ | |
+ // 4015 write | |
+ a4015 = 0x01; | |
+ sound.enableChannel(a4015); | |
+ | |
+ // 4003 write | |
+ sound.setSquareWaveType(0, (a4000>>6)&0x03); | |
+ unsigned short val = ((a4003&0x07)<<8)|a4002; | |
+ val = static_cast<short>(111860.78 / (val+1)); | |
+ sound.play(0, 441); | |
+ | |
+ getchar(); | |
+ | |
+ // 4015 write | |
+ a4015 = 0; | |
+ sound.enableChannel(a4015); | |
+ | |
+ return 0; | |
+} | |
+#endif | |
+ | |
diff --git a/SEAL/WaveCreator.cpp b/SEAL/WaveCreator.cpp | |
index 78c4c08..7a3921b 100644 | |
--- a/SEAL/WaveCreator.cpp | |
+++ b/SEAL/WaveCreator.cpp | |
@@ -1,6 +1,8 @@ | |
#include "WaveCreator.h" | |
#include <memory> | |
+#include <cstring> | |
+ | |
const WORD WAVE_FORMAT = | |
AUDIO_FORMAT_16BITS|AUDIO_FORMAT_MONO|AUDIO_FORMAT_LOOP; | |
diff --git a/SEAL/audio.h b/SEAL/audio.h | |
index 4ee1bf4..4b6123d 100644 | |
--- a/SEAL/audio.h | |
+++ b/SEAL/audio.h | |
@@ -25,7 +25,10 @@ extern "C" { | |
#ifndef WINAPI | |
/* atomic data types definitions */ | |
-typedef void VOID; | |
+ | |
+// This is evil by modern standards, lets just void on our own | |
+//typedef void VOID; | |
+ | |
typedef char CHAR; | |
typedef int INT; | |
typedef long LONG; | |
@@ -36,7 +39,7 @@ typedef unsigned short WORD; | |
typedef unsigned int UINT; | |
typedef unsigned long DWORD; | |
-typedef VOID* LPVOID; | |
+//typedef VOID* LPVOID; | |
typedef CHAR* LPCHAR; | |
typedef INT* LPINT; | |
typedef LONG* LPLONG; | |
@@ -288,9 +291,9 @@ typedef struct { | |
} AUDIOTRACK, *LPAUDIOTRACK; | |
/* audio callback function defines */ | |
-typedef VOID (AIAPI* LPFNAUDIOWAVE)(LPBYTE, UINT); | |
-typedef VOID (AIAPI* LPFNAUDIOTIMER)(VOID); | |
-typedef VOID (AIAPI* LPFNAUDIOCALLBACK)(BYTE, UINT, UINT); | |
+typedef void (AIAPI* LPFNAUDIOWAVE)(LPBYTE, UINT); | |
+typedef void (AIAPI* LPFNAUDIOTIMER)(void); | |
+typedef void (AIAPI* LPFNAUDIOCALLBACK)(BYTE, UINT, UINT); | |
/* audio handle defines */ | |
typedef HANDLE HAC; | |
@@ -299,28 +302,28 @@ typedef HAC* LPHAC; | |
#pragma pack() | |
/* audio interface API prototypes */ | |
-UINT AIAPI AInitialize(VOID); | |
-UINT AIAPI AGetVersion(VOID); | |
-UINT AIAPI AGetAudioNumDevs(VOID); | |
+UINT AIAPI AInitialize(void); | |
+UINT AIAPI AGetVersion(void); | |
+UINT AIAPI AGetAudioNumDevs(void); | |
UINT AIAPI AGetAudioDevCaps(UINT nDeviceId, LPAUDIOCAPS lpCaps); | |
UINT AIAPI AGetErrorText(UINT nErrorCode, LPSTR lpText, UINT nSize); | |
UINT AIAPI APingAudio(LPUINT lpnDeviceId); | |
UINT AIAPI AOpenAudio(LPAUDIOINFO lpInfo); | |
-UINT AIAPI ACloseAudio(VOID); | |
-UINT AIAPI AUpdateAudio(VOID); | |
+UINT AIAPI ACloseAudio(void); | |
+UINT AIAPI AUpdateAudio(void); | |
UINT AIAPI AUpdateAudioEx(UINT nFrames); | |
UINT AIAPI ASetAudioMixerValue(UINT nChannel, UINT nValue); | |
UINT AIAPI AOpenVoices(UINT nVoices); | |
-UINT AIAPI ACloseVoices(VOID); | |
+UINT AIAPI ACloseVoices(void); | |
UINT AIAPI ASetAudioCallback(LPFNAUDIOWAVE lpfnAudioWave); | |
UINT AIAPI ASetAudioTimerProc(LPFNAUDIOTIMER lpfnAudioTimer); | |
UINT AIAPI ASetAudioTimerRate(UINT nTimerRate); | |
-LONG AIAPI AGetAudioDataAvail(VOID); | |
+LONG AIAPI AGetAudioDataAvail(void); | |
UINT AIAPI ACreateAudioData(LPAUDIOWAVE lpWave); | |
UINT AIAPI ADestroyAudioData(LPAUDIOWAVE lpWave); | |
UINT AIAPI AWriteAudioData(LPAUDIOWAVE lpWave, DWORD dwOffset, UINT nCount); | |
@@ -345,9 +348,9 @@ UINT AIAPI AGetVoicePanning(HAC hVoice, LPUINT lpnPanning); | |
UINT AIAPI AGetVoiceStatus(HAC hVoice, LPBOOL lpnStatus); | |
UINT AIAPI APlayModule(LPAUDIOMODULE lpModule); | |
-UINT AIAPI AStopModule(VOID); | |
-UINT AIAPI APauseModule(VOID); | |
-UINT AIAPI AResumeModule(VOID); | |
+UINT AIAPI AStopModule(void); | |
+UINT AIAPI APauseModule(void); | |
+UINT AIAPI AResumeModule(void); | |
UINT AIAPI ASetModuleVolume(UINT nVolume); | |
UINT AIAPI ASetModulePosition(UINT nOrder, UINT nRow); | |
UINT AIAPI AGetModuleVolume(LPUINT lpnVolume); | |
diff --git a/SEAL/libaudio.a b/SEAL/libaudio.a | |
index f7aeabb..5d91914 100644 | |
Binary files a/SEAL/libaudio.a and b/SEAL/libaudio.a differ | |
diff --git a/WeeNES.rdef b/WeeNES.rdef | |
new file mode 100644 | |
index 0000000..c4d7836 | |
--- /dev/null | |
+++ b/WeeNES.rdef | |
@@ -0,0 +1,71 @@ | |
+ | |
+resource app_signature "application/x-vnd.WeeNES"; | |
+ | |
+resource app_version { | |
+ major = 0, | |
+ middle = 5, | |
+ minor = 6, | |
+ | |
+ variety = B_APPV_DEVELOPMENT, | |
+ internal = 0, | |
+ | |
+ short_info = "WeeNES 0.5.6", | |
+ long_info = "WeeNES, the NES emulator for Haiku" | |
+}; | |
+ | |
+resource file_types message { | |
+ "types" = "application/octet-stream" | |
+ }; | |
+ | |
+resource vector_icon { | |
+ $"6E6369660E04003F03A9FF00050003EEEEEC05FF020016003E6C9D3DFD77BDFD" | |
+ $"773E6C9D477C0E4C7B5802011600B2435B3D1D6DBBCE1EB0C3BB48372948418C" | |
+ $"04007E04004C03E9B96E032E343602001600404C69000000000000404646445C" | |
+ $"34452D29020116003C8F440000000000003ACE6D4837B2487FF4020116003C79" | |
+ $"EE0000000000003AA3C34803F94854DA170204C83EC837C83EC79EC83EC8D1BF" | |
+ $"BFC94FC470C94FBB0EC94FB740C837B740C8D1B740C79EBFBFC71FBB0EC71FC4" | |
+ $"70C71F0204C83EC837C83EC79EC83EC8D1BFBFC94FC470C94FBB0EC94FB740C8" | |
+ $"37B740C8D1B740C79EBFBFC71FBB0EC71FC470C71F0605AF03BFB126C673B55D" | |
+ $"B8E0B56CB4F4BF1BB4EAB9D5B500C454BC93C450C20CC441CAA2BF36CAA2C478" | |
+ $"CAA2B9E70605AF03BFB126C673B55DB8E0B56CB4F4BF1BB4EAB9D5B500C454BC" | |
+ $"93C450C20CC441CAA2BF36CAA2C478CAA2B9E70204C1DBB59AC369B5D7C1D0B5" | |
+ $"C6C1C6B626C1C6B5F6C1C6B759C3F7B853C2C2B853C4DAB853C5F5B70CC59EB7" | |
+ $"CDC4C8B6570204C1DBB59AC369B5D7C1D0B5C6C1C6B626C1C6B5F6C1C6B759C3" | |
+ $"F7B853C2C2B853C4DAB853C5F5B70CC59EB7CDC4C8B6570204BDB5B59ABC28B5" | |
+ $"D7BDC1B5C6BDCBB626BDCBB5F6BDCBB759BB9AB853BCCFB853BAB7B853B99CB7" | |
+ $"0CB9F4B7CDBAC8B6570204BDB5B59ABC28B5D7BDC1B5C6BDCBB626BDCBB5F6BD" | |
+ $"CBB759BB9AB853BCCFB853BAB7B853B99CB70CB9F4B7CDBAC8B6570204C32BBC" | |
+ $"97C32BBAC4C32BBE68BFD9BFE2C1AEBFE2BE03BFE3BC87BC97BC86BE68BC86BA" | |
+ $"C4BFD9B94ABE03B94AC1AEB94A0204C32BBC97C32BBAC4C32BBE68BFD9BFE2C1" | |
+ $"AEBFE2BE03BFE3BC87BC97BC86BE68BC86BAC4BFD9B94ABE03B94AC1AEB94A02" | |
+ $"04C7B2B875C93DB9CAC6BEB8E0C5F7BAE3C60CB9C9C5D9BC7DC8A7BE01C70DBD" | |
+ $"E3C954BE0ECA7DBD86C9F8BDDFCA34BB910204C7B2B875C93DB9CAC6BEB8E0C5" | |
+ $"F7BAE3C60CB9C9C5D9BC7DC8A7BE01C70DBDE3C954BE0ECA7DBD86C9F8BDDFCA" | |
+ $"34BB910204B7DFB875B654B9CAB8D3B8E0B99ABAE3B985B9C9B9B8BC7DB6E8BE" | |
+ $"01B883BDE3B63CBE0EB514BD86B59ABDDFB55DBB910204B7DFB875B654B9CAB8" | |
+ $"D3B8E0B99ABAE3B985B9C9B9B8BC7DB6E8BE01B883BDE3B63CBE0EB514BD86B5" | |
+ $"9ABDDFB55DBB910605AF03BFAAB5F3C614B5EDB934B5FAB57DBEF0B573BA10B5" | |
+ $"87C3C3BCB6C3C0C1E8C3B4CA0BBF0ACA0BC3E7CA0BBA1F0204C71FC0DAC71FBE" | |
+ $"7BC71FC33ABFB7C525C3CFC525BB9FC525B84EC0DAB84EC33AB84EBE7CBFB6BC" | |
+ $"8FBB9FBC8FC3CEBC8F0204C71FC0DAC71FBE7BC71FC33ABFB7C525C3CFC525BB" | |
+ $"9FC525B84EC0DAB84EC33AB84EBE7CBFB6BC8FBB9FBC8FC3CEBC8F0209BBE7BF" | |
+ $"29BAE2BF29BBE7BF29C3A9BF29C3A9BF29C4ADBF29C57FC117C57FC006C57FC1" | |
+ $"17C57FC5B8C57FC5B8C57FC6C9C3A9C7A4C4E9C725C264C826C00AC842C1FAC8" | |
+ $"42BE19C842BBE7C7A4BD05C82DBAC2C71ABA11C5B8BA11C6C9BA11C5B8BA11C1" | |
+ $"17BA11C117BA11C0060209BBE7BF29BAE2BF29BBE7BF29C3A9BF29C3A9BF29C4" | |
+ $"ADBF29C57FC117C57FC006C57FC117C57FC5B8C57FC5B8C57FC6C9C3A9C7A4C4" | |
+ $"E9C725C264C826C00AC842C1FAC842BE19C842BBE7C7A4BD05C82DBAC2C71ABA" | |
+ $"11C5B8BA11C6C9BA11C5B8BA11C117BA11C117BA11C0060204BEE7C22DBEE7C1" | |
+ $"93BEE7C2C6BE69C342BEAFC342BE25C342BDECC22DBDECC2C6BDECC193BE69C1" | |
+ $"17BE25C117BEAFC1170204BEE7C22DBEE7C193BEE7C2C6BE69C342BEAFC342BE" | |
+ $"25C342BDECC22DBDECC2C6BDECC193BE69C117BE25C117BEAFC117020446C22D" | |
+ $"46C19346C2C6C19EC342C1E8C342C154C342C119C22DC119C2C6C119C193C19E" | |
+ $"C117C154C117C1E8C117020446C22D46C19346C2C6C19EC342C1E8C342C154C3" | |
+ $"42C119C22DC119C2C6C119C193C19EC117C154C117C1E8C117170A000100000A" | |
+ $"0001011001178100040A010102000A0201031001178100040A030104000A0201" | |
+ $"051001178100040A030106000A0201071001178100040A040108000A02010910" | |
+ $"01178200040A03010A000A02010B1001178100040A03010C000A02010D100117" | |
+ $"8100040A08010F000A0801101001178200040A090111000A0A01121001178100" | |
+ $"040A020113000A0201141001178100040A020115000A0C00000A020116100117" | |
+ $"810004" | |
+}; | |
diff --git a/makefile b/makefile | |
index 6cb7755..339c409 100644 | |
--- a/makefile | |
+++ b/makefile | |
@@ -6,15 +6,17 @@ | |
## Application Specific Settings --------------------------------------------- | |
+LD = g++ | |
+ | |
# specify the name of the binary | |
-NAME=BeNES | |
+NAME=WeeNES | |
# specify the type of binary | |
# APP: Application | |
# SHARED: Shared library or add-on | |
# STATIC: Static library archive | |
# DRIVER: Kernel Driver | |
-TYPE=APP | |
+TYPE=APP | |
# add support for new Pe and Eddie features | |
# to fill in generic makefile | |
@@ -31,16 +33,16 @@ TYPE=APP | |
# are included from different directories. Also note that spaces | |
# in folder names do not work well with this makefile. | |
-SRCS=BeOS/BeNES.cpp BeOS/BeNESApp.cpp BeOS/BeNESJoypad.cpp BeOS/BeNESMenu.cpp BeOS/BeNESWin.cpp M6502/M6502.c Mappers/NesMapperFactory.cpp NES/NesAPU.cpp NES/NesCPU.cpp NES/NesIO.cpp NES/NesMainboard.cpp NES/NesPPU.cpp NES/NesROM.cpp NES/NesRenderInfo.cpp SEAL/NesSound.cpp SEAL/WaveCreator.cpp | |
+SRCS=src/WeeNES.cpp src/WeeNESApp.cpp src/WeeNESJoypad.cpp src/WeeNESMenu.cpp src/WeeNESWin.cpp M6502/M6502.c Mappers/NesMapperFactory.cpp NES/NesAPU.cpp NES/NesCPU.cpp NES/NesIO.cpp NES/NesMainboard.cpp NES/NesPPU.cpp NES/NesROM.cpp NES/NesRenderInfo.cpp SEAL/NesSound.cpp SEAL/WaveCreator.cpp | |
# specify the resource definition files to use | |
# full path or a relative path to the resource file can be used. | |
-RDEFS= | |
+RDEFS=WeeNES.rdef | |
# specify the resource files to use. | |
# full path or a relative path to the resource file can be used. | |
# both RDEFS and RSRCS can be defined in the same makefile. | |
-RSRCS=BeNES.rsrc | |
+RSRCS= | |
# @<-src@ | |
#%} | |
@@ -57,7 +59,7 @@ RSRCS=BeNES.rsrc | |
# naming scheme you need to specify the path to the library | |
# and it's name | |
# library: my_lib.a entry: my_lib.a or path/my_lib.a | |
-LIBS= | |
+LIBS=SEAL/libaudio.a | |
# specify additional paths to directories following the standard | |
# libXXX.so or libXXX.a naming scheme. You can specify full paths | |
@@ -65,21 +67,21 @@ LIBS= | |
# be recursive, so include all of the paths where libraries can | |
# be found. Directories where source files are found are | |
# automatically included. | |
-LIBPATHS= | |
+LIBPATHS= | |
# additional paths to look for system headers | |
# thes use the form: #include <header> | |
# source file directories are NOT auto-included here | |
-SYSTEM_INCLUDE_PATHS = ./NES ./SEAL ./AbstructClasses ./M6502 | |
+SYSTEM_INCLUDE_PATHS=./NES ./SEAL ./AbstructClasses ./M6502 | |
# additional paths to look for local headers | |
# thes use the form: #include "header" | |
# source file directories are automatically included | |
-LOCAL_INCLUDE_PATHS = ./NES ./SEAL ./AbstructClasses ./M6502 | |
+LOCAL_INCLUDE_PATHS=./NES ./SEAL ./AbstructClasses ./M6502 | |
# specify the level of optimization that you desire | |
# NONE, SOME, FULL | |
-OPTIMIZE= | |
+OPTIMIZE=NONE | |
# specify any preprocessor symbols to be defined. The symbols will not | |
# have their values set automatically; you must supply the value (if any) | |
@@ -92,35 +94,35 @@ DEFINES= | |
# if unspecified default warnings will be used | |
# NONE = supress all warnings | |
# ALL = enable all warnings | |
-WARNINGS = | |
+WARNINGS= | |
# specify whether image symbols will be created | |
# so that stack crawls in the debugger are meaningful | |
# if TRUE symbols will be created | |
-SYMBOLS = | |
+SYMBOLS= | |
# specify debug settings | |
# if TRUE will allow application to be run from a source-level | |
# debugger. Note that this will disable all optimzation. | |
-DEBUGGER = | |
+DEBUGGER= | |
# specify additional compiler flags for all files | |
-COMPILER_FLAGS = | |
+COMPILER_FLAGS= | |
# specify additional linker flags | |
-LINKER_FLAGS = | |
+LINKER_FLAGS=-lbe -ldevice -ltracker -lmedia | |
# specify the version of this particular item | |
# (for example, -app 3 4 0 d 0 -short 340 -long "340 "`echo -n -e '\302\251'`"1999 GNU GPL") | |
# This may also be specified in a resource. | |
-APP_VERSION = | |
+APP_VERSION= | |
# (for TYPE == DRIVER only) Specify desired location of driver in the /dev | |
# hierarchy. Used by the driverinstall rule. E.g., DRIVER_PATH = video/usb will | |
# instruct the driverinstall rule to place a symlink to your driver's binary in | |
# ~/add-ons/kernel/drivers/dev/video/usb, so that your driver will appear at | |
# /dev/video/usb when loaded. Default is "misc". | |
-DRIVER_PATH = | |
+DRIVER_PATH= | |
## include the makefile-engine | |
include $(BUILDHOME)/etc/makefile-engine | |
diff --git a/src/WeeFunctions.h b/src/WeeFunctions.h | |
new file mode 100644 | |
index 0000000..56328d8 | |
--- /dev/null | |
+++ b/src/WeeFunctions.h | |
@@ -0,0 +1,9 @@ | |
+#ifndef BEFUNCTIONS_H_DEFINED | |
+#define BEFUNCTIONS_H_DEFINED | |
+ | |
+inline void HaikuInfobox(char* msg) { | |
+ BAlert* alert = new BAlert(NULL, msg, "OK"); | |
+ alert->Go(); | |
+} | |
+ | |
+#endif | |
diff --git a/src/WeeNES.cpp b/src/WeeNES.cpp | |
new file mode 100644 | |
index 0000000..241c56a | |
--- /dev/null | |
+++ b/src/WeeNES.cpp | |
@@ -0,0 +1,30 @@ | |
+/* | |
+** WeeNES - Nintendo Entertaiment System Emulator for Haiku | |
+** | |
+** * 2010 Alexander von Gluck (WeeNES) | |
+** * 1999 by makoto yamagata (BeNES) | |
+** | |
+** This program is free software; you can redistribute it and/or modify | |
+** it under the terms of the GNU General Public License as published by | |
+** the Free Software Foundation; either version 2 of the License, or | |
+** (at your option) any later version. | |
+** | |
+** This program is distributed in the hope that it will be useful, | |
+** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+** GNU General Public License for more details. | |
+** | |
+** You should have received a copy of the GNU General Public License | |
+** along with this program; if not, write to the Free Software | |
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
+*/ | |
+#include "WeeNESApp.h" | |
+ | |
+int main(void) | |
+{ | |
+ WeeNESApp* app = new WeeNESApp; | |
+ | |
+ app->Run(); | |
+ | |
+ return 0; | |
+} | |
diff --git a/src/WeeNESApp.cpp b/src/WeeNESApp.cpp | |
new file mode 100644 | |
index 0000000..606efb9 | |
--- /dev/null | |
+++ b/src/WeeNESApp.cpp | |
@@ -0,0 +1,250 @@ | |
+/* | |
+** BeNES - Nintendo Entertaiment System Emulator for BeOS | |
+** | |
+** * 1999 by makoto yamagata | |
+** | |
+** This program is free software; you can redistribute it and/or modify | |
+** it under the terms of the GNU General Public License as published by | |
+** the Free Software Foundation; either version 2 of the License, or | |
+** (at your option) any later version. | |
+** | |
+** This program is distributed in the hope that it will be useful, | |
+** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+** GNU General Public License for more details. | |
+** | |
+** You should have received a copy of the GNU General Public License | |
+** along with this program; if not, write to the Free Software | |
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
+*/ | |
+#include <storage/FilePanel.h> | |
+#include <storage/Path.h> | |
+#include <interface/Alert.h> | |
+#include <interface/MenuItem.h> | |
+#include <stdio.h> | |
+#include "WeeNESApp.h" | |
+#include "WeeNESWin.h" | |
+#include "WeeNESMsg.h" | |
+#include "WeeNESJoypad.h" | |
+#include "NesException.h" | |
+#include "NesMainboard.h" | |
+#include "WeeFunctions.h" | |
+ | |
+#define INFO_FORM "\ | |
+Mapper: %02d\n\ | |
+PRG BANKS: %02ld\n\ | |
+CHR BANKS: %02ld\n\ | |
+MIRRORING: %s\n\ | |
+SAVERAM: %s\n\ | |
+TRAINER: %s" | |
+ | |
+#define ABOUT_FORM "WeeNES version 0.5.6\n Released as GPLv2,\n 2010 Alexander von Gluck\n\nBased on BeNES, 1999 Makoto Yamagata" | |
+ | |
+int32 WeeNESApp::RunWeeNES(void* arg) | |
+{ | |
+ NesMainboard* obj = reinterpret_cast<NesMainboard*>(arg); | |
+ obj->run(); | |
+ return 0; | |
+} | |
+ | |
+void WeeNESApp::beginThread() | |
+{ | |
+ mThread = spawn_thread(WeeNESApp::RunWeeNES, | |
+ "WeeNES", B_NORMAL_PRIORITY, &mMainboard); | |
+ resume_thread(mThread); | |
+} | |
+ | |
+void WeeNESApp::endThread() | |
+{ | |
+ if (mThread) { | |
+ status_t result; | |
+ mMainboard.stop(); | |
+ wait_for_thread(mThread, &result); | |
+ kill_thread(mThread); | |
+ mThread = 0; | |
+ } | |
+} | |
+ | |
+void WeeNESApp::ReadyToRun() | |
+{ | |
+ mOpenPanel = new BFilePanel; | |
+ mWindow = new WeeNESWin; | |
+ mJoypad = new WeeNESJoypad; | |
+ mOpenPanel->SetPanelDirectory("./"); | |
+ mMainboard.connectDisplay(mWindow); | |
+ mMainboard.connectJoypad(mJoypad); | |
+ setSkipFrames(2); | |
+ setFPS(60); | |
+ setSound(true); | |
+ setInput(2); | |
+ mWindow->Show(); | |
+} | |
+ | |
+void WeeNESApp::RefsReceived(BMessage* msg) | |
+{ | |
+ BMenuItem* infoItem = mWindow->getMenubar()->FindItem(BENES_INFO); | |
+ infoItem->SetEnabled(false); | |
+ | |
+ entry_ref ref; | |
+ msg->FindRef("refs", 0, &ref); | |
+ | |
+ BEntry entry(&ref); | |
+ BPath path; | |
+ entry.GetPath(&path); | |
+ | |
+ try { | |
+ endThread(); | |
+ mWindow->clear(); | |
+ mROM.loadRomImage(path.Path()); | |
+ infoItem->SetEnabled(true); | |
+ mMainboard.insertROM(&mROM); | |
+ beginThread(); | |
+ } | |
+ catch (std::bad_alloc& x) { | |
+ HaikuInfobox((char *)"Can't alloc memory..."); | |
+ } | |
+ catch (Nes::FileOpenError& x) { | |
+ HaikuInfobox((char *)"Can't open file..."); | |
+ } | |
+ catch (Nes::UnknownFormat& x) { | |
+ HaikuInfobox((char *)"Unknown NES rom format..."); | |
+ } | |
+ catch (Nes::UnknownMapper& x) { | |
+ char buff[256]; | |
+ sprintf(buff, "Unknown mapper = %d", x.mapper()); | |
+ HaikuInfobox(buff); | |
+ } | |
+ | |
+} | |
+ | |
+bool WeeNESApp::QuitRequested() | |
+{ | |
+ endThread(); | |
+ return true; | |
+} | |
+ | |
+void WeeNESApp::MessageReceived(BMessage* msg) | |
+{ | |
+ switch (msg->what) { | |
+ case BENES_OPEN: | |
+ mOpenPanel->Show(); | |
+ break; | |
+ case BENES_INFO: | |
+ showRomInfo(); | |
+ break; | |
+ case WEE_ABOUT: | |
+ showAboutDialog(); | |
+ break; | |
+ case BENES_FRAMESKIP0: setSkipFrames(0); break; | |
+ case BENES_FRAMESKIP1: setSkipFrames(1); break; | |
+ case BENES_FRAMESKIP2: setSkipFrames(2); break; | |
+ case BENES_FRAMESKIP3: setSkipFrames(3); break; | |
+ case BENES_FRAMESKIP4: setSkipFrames(4); break; | |
+ case BENES_FRAMES30: setFPS(30); break; | |
+ case BENES_FRAMES40: setFPS(40); break; | |
+ case BENES_FRAMES50: setFPS(50); break; | |
+ case BENES_FRAMES60: setFPS(60); break; | |
+ case BENES_FRAMESXX: setFPS(00); break; | |
+ case BENES_ENABLESND: setSound(true); break; | |
+ case BENES_DISABLESND: setSound(false); break; | |
+ case BENES_INPUTJOYSTICK: setInput(0); break; | |
+ case BENES_INPUTJOYPRO: setInput(1); break; | |
+ case BENES_INPUTKEYBOARD: setInput(2); break; | |
+ default: | |
+ BApplication::MessageReceived(msg); | |
+ break; | |
+ } | |
+} | |
+ | |
+void WeeNESApp::showRomInfo() | |
+{ | |
+ char buff[512]; | |
+ sprintf(buff, INFO_FORM, | |
+ mROM.getMapperNumber(), | |
+ mROM.sizeofPRGBANKS(), | |
+ mROM.sizeofCHRBANKS(), | |
+ mROM.isVerticalMirror()? "VERTICAL": "HORIZONTAL", | |
+ mROM.hasSaveRam()? "YES":"NO", | |
+ mROM.hasTrainer()? "YES":"NO"); | |
+ HaikuInfobox(buff); | |
+} | |
+ | |
+void WeeNESApp::showAboutDialog() | |
+{ | |
+ char buff[512]; | |
+ sprintf(buff, ABOUT_FORM); | |
+ HaikuInfobox(buff); | |
+} | |
+ | |
+void WeeNESApp::setSkipFrames(int skip) | |
+{ | |
+ static uint32 cmdID[5] = { | |
+ BENES_FRAMESKIP0, | |
+ BENES_FRAMESKIP1, | |
+ BENES_FRAMESKIP2, | |
+ BENES_FRAMESKIP3, | |
+ BENES_FRAMESKIP4, | |
+ }; | |
+ BMenu* menu = mWindow->getSkipFramesMenu(); | |
+ BMenuItem* item = menu->FindMarked(); | |
+ if (item) item->SetMarked(false); | |
+ item = mWindow->getMenubar()->FindItem(cmdID[skip]); | |
+ if (item) item->SetMarked(true); | |
+ | |
+ mMainboard.setSkipFrames(skip); | |
+} | |
+ | |
+void WeeNESApp::setFPS(int fps) | |
+{ | |
+ BMenu* menu = mWindow->getFramesParSecMenu(); | |
+ BMenuItem* item = menu->FindMarked(); | |
+ if (item) item->SetMarked(false); | |
+ int32 cmdID; | |
+ switch (fps) { | |
+ case 30: cmdID = BENES_FRAMES30; break; | |
+ case 40: cmdID = BENES_FRAMES40; break; | |
+ case 50: cmdID = BENES_FRAMES50; break; | |
+ case 60: cmdID = BENES_FRAMES60; break; | |
+ default: cmdID = BENES_FRAMESXX; break; | |
+ } | |
+ item = mWindow->getMenubar()->FindItem(cmdID); | |
+ if (item) item->SetMarked(true); | |
+ | |
+ mWindow->setFPS(fps); | |
+} | |
+ | |
+void WeeNESApp::setSound(bool on) | |
+{ | |
+ BMenu* menu = mWindow->getSoundMenu(); | |
+ BMenuItem* item = menu->FindMarked(); | |
+ if (item) item->SetMarked(false); | |
+ int32 cmdID; | |
+ if (on) { | |
+ cmdID = BENES_ENABLESND; | |
+ } | |
+ else { | |
+ cmdID = BENES_DISABLESND; | |
+ } | |
+ item = mWindow->getMenubar()->FindItem(cmdID); | |
+ if (item) item->SetMarked(true); | |
+ | |
+ mMainboard.enableSound(on); | |
+} | |
+ | |
+void WeeNESApp::setInput(int type) | |
+{ | |
+ BMenu* menu = mWindow->getInputMenu(); | |
+ BMenuItem* item = menu->FindMarked(); | |
+ if (item) item->SetMarked(false); | |
+ int32 cmdID; | |
+ switch (type) { | |
+ case 0: cmdID = BENES_INPUTJOYSTICK; break; | |
+ case 1: cmdID = BENES_INPUTJOYPRO; break; | |
+ case 2: cmdID = BENES_INPUTKEYBOARD; break; | |
+ default: cmdID = BENES_INPUTKEYBOARD; | |
+ } | |
+ item = mWindow->getMenubar()->FindItem(cmdID); | |
+ if (item) item->SetMarked(true); | |
+ | |
+ mJoypad->setInput(type); | |
+} | |
diff --git a/src/WeeNESApp.h b/src/WeeNESApp.h | |
new file mode 100644 | |
index 0000000..c7cb5bb | |
--- /dev/null | |
+++ b/src/WeeNESApp.h | |
@@ -0,0 +1,68 @@ | |
+/* | |
+** BeNES - Nintendo Entertaiment System Emulator for BeOS | |
+** | |
+** * 1999 by makoto yamagata | |
+** | |
+** This program is free software; you can redistribute it and/or modify | |
+** it under the terms of the GNU General Public License as published by | |
+** the Free Software Foundation; either version 2 of the License, or | |
+** (at your option) any later version. | |
+** | |
+** This program is distributed in the hope that it will be useful, | |
+** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+** GNU General Public License for more details. | |
+** | |
+** You should have received a copy of the GNU General Public License | |
+** along with this program; if not, write to the Free Software | |
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
+*/ | |
+#ifndef BENESAPP_H_DEFINED | |
+#define BENESAPP_H_DEFINED | |
+ | |
+#include <app/Application.h> | |
+#include <storage/FilePanel.h> | |
+#include <interface/MenuBar.h> | |
+#include "NesROM.h" | |
+#include "NesMainboard.h" | |
+ | |
+class WeeNESWin; | |
+class WeeNESJoypad; | |
+ | |
+class WeeNESApp: public BApplication { | |
+ thread_id mThread; | |
+ BFilePanel* mOpenPanel; | |
+ WeeNESWin* mWindow; | |
+ WeeNESJoypad* mJoypad; | |
+ NesROM mROM; | |
+ NesMainboard mMainboard; | |
+public: | |
+ | |
+ WeeNESApp(): | |
+ BApplication("application/x-vnd.WeeNES"), | |
+ mThread(0), | |
+ mOpenPanel(NULL), | |
+ mWindow(NULL), | |
+ mJoypad(NULL) { ; } | |
+ ~WeeNESApp() { | |
+ endThread(); | |
+ } | |
+private: | |
+ // system | |
+ void ReadyToRun(); | |
+ void RefsReceived(BMessage* msg); | |
+ void MessageReceived(BMessage* msg); | |
+ bool QuitRequested(); | |
+ // user | |
+ void showRomInfo(); | |
+ void showAboutDialog(); | |
+ void beginThread(); | |
+ void endThread(); | |
+ static int32 RunWeeNES(void* arg); | |
+ void setSkipFrames(int skip); | |
+ void setFPS(int fps); | |
+ void setSound(bool on); | |
+ void setInput(int type); | |
+}; | |
+ | |
+#endif | |
diff --git a/src/WeeNESJoypad.cpp b/src/WeeNESJoypad.cpp | |
new file mode 100644 | |
index 0000000..c78106a | |
--- /dev/null | |
+++ b/src/WeeNESJoypad.cpp | |
@@ -0,0 +1,200 @@ | |
+#include "WeeNESJoypad.h" | |
+#include <interface/InterfaceDefs.h> | |
+#include <device/Joystick.h> | |
+ | |
+#include <stdio.h> | |
+#include <unistd.h> | |
+ | |
+const char *PORTNAME="gameport/201"; | |
+ | |
+inline bool isKeyDown(key_info& info, unsigned char key) | |
+{ | |
+ return (info.key_states[key>>3] & (1<<(7-(key&7)))); | |
+} | |
+ | |
+#define RETURN 0x47 | |
+#define SPACE 0x5e | |
+#define UP 0x57 | |
+#define DOWN 0x62 | |
+#define LEFT 0x61 | |
+#define RIGHT 0x63 | |
+#define LSHIFT 0x4b | |
+#define A 0x4c | |
+#define B 0x4d | |
+ | |
+#define PTOLERANCE 100 | |
+#define NTOLERANCE -100 | |
+ | |
+WeeNESJoypad::WeeNESJoypad(): NesJoypad() | |
+{ | |
+ mThread = spawn_thread(WeeNESJoypad::Polling, | |
+ "BeNESJoy", B_NORMAL_PRIORITY, this); | |
+ resume_thread(mThread); | |
+ inputType=2; | |
+ mRunning = true; | |
+} | |
+ | |
+WeeNESJoypad::~WeeNESJoypad() | |
+{ | |
+ if (mThread) { | |
+ status_t result; | |
+ mRunning = false; | |
+ wait_for_thread(mThread, &result); | |
+ kill_thread(mThread); | |
+ } | |
+} | |
+ | |
+void WeeNESJoypad::setInput(int type) | |
+{ | |
+ inputType = type; | |
+} | |
+ | |
+int32 WeeNESJoypad::Polling(void* arg) | |
+{ | |
+ const int pollingRate = 1000000 / 60; | |
+ BJoystick bjoy; | |
+ status_t st; | |
+ int32 buttonstat; | |
+ int16 axesstat[2]; | |
+ WeeNESJoypad* joy = reinterpret_cast<WeeNESJoypad*>(arg); | |
+ key_info info; | |
+ int type; | |
+ | |
+ st = bjoy.Open(PORTNAME); | |
+ | |
+ while (joy->mRunning) | |
+ { | |
+ snooze(pollingRate); | |
+ type = joy->inputType; | |
+ | |
+ if (type==2) | |
+ { | |
+ get_key_info(&info); | |
+ | |
+ if (isKeyDown(info, A)) joy->pushA(); | |
+ else joy->releaseA(); | |
+ | |
+ if (isKeyDown(info, B) || isKeyDown(info, LSHIFT)) joy->pushB(); | |
+ else joy->releaseB(); | |
+ | |
+ if (isKeyDown(info, RETURN)) joy->pushStart(); | |
+ else joy->releaseStart(); | |
+ | |
+ if (isKeyDown(info, SPACE)) joy->pushSelect(); | |
+ else joy->releaseSelect(); | |
+ | |
+ if (isKeyDown(info, UP)) joy->pushUp(); | |
+ else joy->releaseUp(); | |
+ | |
+ if (isKeyDown(info, DOWN)) joy->pushDown(); | |
+ else joy->releaseDown(); | |
+ | |
+ if (isKeyDown(info, LEFT)) joy->pushLeft(); | |
+ else joy->releaseLeft(); | |
+ | |
+ if (isKeyDown(info, RIGHT)) joy->pushRight(); | |
+ else joy->releaseRight(); | |
+ } | |
+ else if(type==1) | |
+ { | |
+ joy->releaseA(); | |
+ joy->releaseB(); | |
+ joy->releaseSelect(); | |
+ joy->releaseStart(); | |
+ joy->releaseUp(); | |
+ joy->releaseDown(); | |
+ joy->releaseLeft(); | |
+ joy->releaseRight(); | |
+ | |
+ bjoy.Update(); | |
+ buttonstat = bjoy.ButtonValues(); | |
+ bjoy.GetAxisValues(axesstat); | |
+ | |
+ if (buttonstat) | |
+ { | |
+ if ((buttonstat & 8)==8) joy->pushA(); | |
+ | |
+ if((buttonstat & 16) == 16) joy->pushB(); | |
+ | |
+ if((buttonstat & 256) == 256) joy->pushStart(); | |
+ | |
+ if ((buttonstat & 512) == 512) joy->pushSelect(); | |
+ } | |
+ if (*(axesstat+1)) | |
+ { | |
+ if (*(axesstat+1) > 0) | |
+ { | |
+ joy->pushUp(); | |
+ } | |
+ else if (*(axesstat+1) < 0) | |
+ { | |
+ joy->pushDown(); | |
+ } | |
+ } | |
+ | |
+ if (*(axesstat)) | |
+ { | |
+ if (*(axesstat) > 0) | |
+ { | |
+ joy->pushRight(); | |
+ } | |
+ else if (*(axesstat) < 0) | |
+ { | |
+ joy->pushLeft(); | |
+ } | |
+ } | |
+ } | |
+ else if(type==0) | |
+ { | |
+ joy->releaseA(); | |
+ joy->releaseB(); | |
+ joy->releaseSelect(); | |
+ joy->releaseStart(); | |
+ joy->releaseUp(); | |
+ joy->releaseDown(); | |
+ joy->releaseLeft(); | |
+ joy->releaseRight(); | |
+ | |
+ bjoy.Update(); | |
+ buttonstat = bjoy.ButtonValues(); | |
+ bjoy.GetAxisValues(axesstat); | |
+ | |
+ if (buttonstat) | |
+ { | |
+ if ((buttonstat & 2)==2) joy->pushA(); | |
+ | |
+ if((buttonstat & 1) == 1) joy->pushB(); | |
+ | |
+ if((buttonstat & 4) == 4) joy->pushStart(); | |
+ | |
+ if ((buttonstat & 8) == 8) joy->pushSelect(); | |
+ } | |
+ if (*(axesstat+1)) | |
+ { | |
+ if (*(axesstat+1) > PTOLERANCE) | |
+ { | |
+ joy->pushDown(); | |
+ } | |
+ else if (*(axesstat+1) < NTOLERANCE) | |
+ { | |
+ joy->pushUp(); | |
+ } | |
+ } | |
+ | |
+ if (*(axesstat)) | |
+ { | |
+ if (*(axesstat) > 0) | |
+ { | |
+ joy->pushRight(); | |
+ } | |
+ else if (*(axesstat) < 0) | |
+ { | |
+ joy->pushLeft(); | |
+ } | |
+ } | |
+ } | |
+ | |
+ | |
+ } | |
+ return 0; | |
+} | |
diff --git a/src/WeeNESJoypad.h b/src/WeeNESJoypad.h | |
new file mode 100644 | |
index 0000000..36d92e7 | |
--- /dev/null | |
+++ b/src/WeeNESJoypad.h | |
@@ -0,0 +1,18 @@ | |
+#ifndef BENESJOYPAD_H_DEFINED | |
+#define BENESJOYPAD_H_DEFINED | |
+ | |
+#include "NesJoypad.h" | |
+#include <be/kernel/OS.h> | |
+ | |
+class WeeNESJoypad: public NesJoypad { | |
+ thread_id mThread; | |
+ bool mRunning; | |
+ int inputType; | |
+public: | |
+ WeeNESJoypad(); | |
+ ~WeeNESJoypad(); | |
+ static int32 Polling(void* arg); | |
+ void setInput(int type); | |
+}; | |
+ | |
+#endif | |
diff --git a/src/WeeNESMenu.cpp b/src/WeeNESMenu.cpp | |
new file mode 100644 | |
index 0000000..3a8967a | |
--- /dev/null | |
+++ b/src/WeeNESMenu.cpp | |
@@ -0,0 +1,139 @@ | |
+/* | |
+** BeNES - Nintendo Entertaiment System Emulator for BeOS | |
+** | |
+** * 1999 by makoto yamagata | |
+** | |
+** This program is free software; you can redistribute it and/or modify | |
+** it under the terms of the GNU General Public License as published by | |
+** the Free Software Foundation; either version 2 of the License, or | |
+** (at your option) any later version. | |
+** | |
+** This program is distributed in the hope that it will be useful, | |
+** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+** GNU General Public License for more details. | |
+** | |
+** You should have received a copy of the GNU General Public License | |
+** along with this program; if not, write to the Free Software | |
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
+*/ | |
+#include <app/Application.h> | |
+#include <interface/MenuItem.h> | |
+#include "WeeNESMenu.h" | |
+#include "WeeNESMsg.h" | |
+ | |
+using std::string; | |
+ | |
+const string WeeNESMenu::File = "File"; | |
+const string WeeNESMenu::Setting = "Setting"; | |
+const string WeeNESMenu::Help = "Help"; | |
+const string WeeNESMenu::FrameSkip = "Skip Frames"; | |
+const string WeeNESMenu::FramesParSec = "Frames Par Sec."; | |
+const string WeeNESMenu::Sound = "Sound"; | |
+const string WeeNESMenu::Input = "Input"; | |
+ | |
+BMenu* WeeNESMenu::buildFileMenu() | |
+{ | |
+ // Build File Menu | |
+ BMenu* menu = new BMenu(File.c_str()); | |
+ BMenuItem* item = NULL; | |
+ item = new BMenuItem("Open...", new BMessage(BENES_OPEN), 'O'); | |
+ menu->AddItem(item); | |
+ menu->AddSeparatorItem(); | |
+ item = new BMenuItem("ROM Info...", new BMessage(BENES_INFO), 'I'); | |
+ item->SetEnabled(false); | |
+ menu->AddItem(item); | |
+ menu->AddSeparatorItem(); | |
+ item = new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED), 'Q'); | |
+ menu->AddItem(item); | |
+ | |
+ menu->SetTargetForItems(be_app); | |
+ | |
+ return menu; | |
+} | |
+ | |
+BMenu* WeeNESMenu::buildSettingMenu() | |
+{ | |
+ BMenuItem* item = NULL; | |
+ | |
+ // Build FrameSkip SubMenu | |
+ BMenu* skip = new BMenu(FrameSkip.c_str()); | |
+ item = new BMenuItem("0", new BMessage(BENES_FRAMESKIP0)); | |
+ skip->AddItem(item); | |
+ item = new BMenuItem("1", new BMessage(BENES_FRAMESKIP1)); | |
+ skip->AddItem(item); | |
+ item = new BMenuItem("2", new BMessage(BENES_FRAMESKIP2)); | |
+ skip->AddItem(item); | |
+ item = new BMenuItem("3", new BMessage(BENES_FRAMESKIP3)); | |
+ skip->AddItem(item); | |
+ item = new BMenuItem("4", new BMessage(BENES_FRAMESKIP4)); | |
+ skip->AddItem(item); | |
+ skip->SetTargetForItems(be_app); | |
+ | |
+ // Build Frames par sec SubMenu | |
+ BMenu* fps = new BMenu(FramesParSec.c_str()); | |
+ item = new BMenuItem("30", new BMessage(BENES_FRAMES30)); | |
+ fps->AddItem(item); | |
+ item = new BMenuItem("40", new BMessage(BENES_FRAMES40)); | |
+ fps->AddItem(item); | |
+ item = new BMenuItem("50", new BMessage(BENES_FRAMES50)); | |
+ fps->AddItem(item); | |
+ item = new BMenuItem("60", new BMessage(BENES_FRAMES60)); | |
+ fps->AddItem(item); | |
+ item = new BMenuItem("MAX", new BMessage(BENES_FRAMESXX)); | |
+ fps->AddItem(item); | |
+ fps->SetTargetForItems(be_app); | |
+ | |
+ // Build Sound SubMenu | |
+ BMenu* snd = new BMenu(Sound.c_str()); | |
+ item = new BMenuItem("Enable", new BMessage(BENES_ENABLESND)); | |
+ snd->AddItem(item); | |
+ item = new BMenuItem("Disable", new BMessage(BENES_DISABLESND)); | |
+ snd->AddItem(item); | |
+ snd->SetTargetForItems(be_app); | |
+ | |
+ //Build Input Menu | |
+ BMenu* inp = new BMenu(Input.c_str()); | |
+ item = new BMenuItem("Joystick", new BMessage(BENES_INPUTJOYSTICK)); | |
+ inp->AddItem(item); | |
+ item = new BMenuItem("Gamepad Pro", new BMessage(BENES_INPUTJOYPRO)); | |
+ inp->AddItem(item); | |
+ item = new BMenuItem("Keyboard", new BMessage(BENES_INPUTKEYBOARD)); | |
+ inp->AddItem(item); | |
+ inp->SetTargetForItems(be_app); | |
+ | |
+ // Build Setting Menu | |
+ BMenu* menu = new BMenu(Setting.c_str()); | |
+ menu->AddItem(skip); | |
+ menu->AddItem(fps); | |
+ menu->AddItem(snd); | |
+ menu->AddItem(inp); | |
+ menu->SetTargetForItems(be_app); | |
+ | |
+ return menu; | |
+} | |
+ | |
+BMenu* WeeNESMenu::buildHelpMenu() | |
+{ | |
+ // Build File Menu | |
+ BMenu* menu = new BMenu(Help.c_str()); | |
+ BMenuItem* item = NULL; | |
+ item = new BMenuItem("About", new BMessage(WEE_ABOUT), 'A'); | |
+ menu->AddItem(item); | |
+ | |
+ menu->SetTargetForItems(be_app); | |
+ | |
+ return menu; | |
+} | |
+ | |
+BMenuBar* WeeNESMenu::Build() | |
+{ | |
+ BMenuBar* bar = new BMenuBar(BRect(), B_EMPTY_STRING); | |
+ // File Menu | |
+ bar->AddItem(buildFileMenu()); | |
+ // Setting Menu | |
+ bar->AddItem(buildSettingMenu()); | |
+ // Help Menu | |
+ bar->AddItem(buildHelpMenu()); | |
+ return bar; | |
+} | |
diff --git a/src/WeeNESMenu.h b/src/WeeNESMenu.h | |
new file mode 100644 | |
index 0000000..95a4839 | |
--- /dev/null | |
+++ b/src/WeeNESMenu.h | |
@@ -0,0 +1,45 @@ | |
+/* | |
+** BeNES - Nintendo Entertaiment System Emulator for BeOS | |
+** | |
+** * 1999 by makoto yamagata | |
+** | |
+** This program is free software; you can redistribute it and/or modify | |
+** it under the terms of the GNU General Public License as published by | |
+** the Free Software Foundation; either version 2 of the License, or | |
+** (at your option) any later version. | |
+** | |
+** This program is distributed in the hope that it will be useful, | |
+** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+** GNU General Public License for more details. | |
+** | |
+** You should have received a copy of the GNU General Public License | |
+** along with this program; if not, write to the Free Software | |
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
+*/ | |
+#ifndef BENESMENU_H_DEFINED | |
+#define BENESMENU_H_DEFINED | |
+ | |
+#include <interface/MenuBar.h> | |
+#include <string> | |
+ | |
+using std::string; | |
+ | |
+class WeeNESMenu { | |
+ WeeNESMenu() {}; | |
+public: | |
+ static const string File; | |
+ static const string Setting; | |
+ static const string FrameSkip; | |
+ static const string FramesParSec; | |
+ static const string Help; | |
+ static const string Sound; | |
+ static const string Input; | |
+ static BMenuBar* Build(); | |
+private: | |
+ static BMenu* buildFileMenu(); | |
+ static BMenu* buildSettingMenu(); | |
+ static BMenu* buildHelpMenu(); | |
+}; | |
+ | |
+#endif | |
diff --git a/src/WeeNESMenuBuilder.h b/src/WeeNESMenuBuilder.h | |
new file mode 100644 | |
index 0000000..c892f03 | |
--- /dev/null | |
+++ b/src/WeeNESMenuBuilder.h | |
@@ -0,0 +1,35 @@ | |
+/* | |
+** BeNES - Nintendo Entertaiment System Emulator for BeOS | |
+** | |
+** * 1999 by makoto yamagata | |
+** | |
+** This program is free software; you can redistribute it and/or modify | |
+** it under the terms of the GNU General Public License as published by | |
+** the Free Software Foundation; either version 2 of the License, or | |
+** (at your option) any later version. | |
+** | |
+** This program is distributed in the hope that it will be useful, | |
+** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+** GNU General Public License for more details. | |
+** | |
+** You should have received a copy of the GNU General Public License | |
+** along with this program; if not, write to the Free Software | |
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
+*/ | |
+#ifndef BENESMENUBUILDER_H_DEFINED | |
+#define BENESMENUBUILDER_H_DEFINED | |
+ | |
+#include <interface/MenuBar.h> | |
+ | |
+class WeeNESMenu { | |
+ WeeNESMenu() {}; | |
+public: | |
+ static BMenuBar* Build(); | |
+private: | |
+ static BMenu* buildFileMenu(); | |
+ static BMenu* buildSettingMenu(); | |
+ static BMenu* buildHelpMenu(); | |
+}; | |
+ | |
+#endif | |
diff --git a/src/WeeNESMsg.h b/src/WeeNESMsg.h | |
new file mode 100644 | |
index 0000000..c86b5f6 | |
--- /dev/null | |
+++ b/src/WeeNESMsg.h | |
@@ -0,0 +1,28 @@ | |
+#ifndef BENESMSG_H_DEFINED | |
+#define BENESMSG_H_DEFINED | |
+ | |
+const uint32 BENES_OPEN = 'OpeN'; | |
+const uint32 BENES_INFO = 'InfO'; | |
+const uint32 WEE_ABOUT = 'Abou'; | |
+ | |
+const uint32 BENES_FRAMESKIP0 = 'SKP0'; | |
+const uint32 BENES_FRAMESKIP1 = 'SKP1'; | |
+const uint32 BENES_FRAMESKIP2 = 'SKP2'; | |
+const uint32 BENES_FRAMESKIP3 = 'SKP3'; | |
+const uint32 BENES_FRAMESKIP4 = 'SKP4'; | |
+ | |
+const uint32 BENES_FRAMES30 = 'FPS3'; | |
+const uint32 BENES_FRAMES40 = 'FPS4'; | |
+const uint32 BENES_FRAMES50 = 'FPS5'; | |
+const uint32 BENES_FRAMES60 = 'FPS6'; | |
+const uint32 BENES_FRAMESXX = 'FPSX'; | |
+ | |
+const uint32 BENES_ENABLESND = 'ESND'; | |
+const uint32 BENES_DISABLESND = 'DSND'; | |
+ | |
+const uint32 BENES_INPUTJOYSTICK = 'JSTK'; | |
+const uint32 BENES_INPUTJOYPRO = 'JPRO'; | |
+const uint32 BENES_INPUTKEYBOARD = 'KEYB'; | |
+ | |
+ | |
+#endif | |
diff --git a/src/WeeNESPalette.h b/src/WeeNESPalette.h | |
new file mode 100644 | |
index 0000000..fe771d5 | |
--- /dev/null | |
+++ b/src/WeeNESPalette.h | |
@@ -0,0 +1,41 @@ | |
+#ifndef BENESPALETTE_H_DEFINED | |
+#define BENESPALETTE_H_DEFINED | |
+ | |
+#include <interface/GraphicsDefs.h> | |
+ | |
+rgb_color WeeNESPalette[64] = { | |
+ { 0x7f,0x7f,0x7f,0xff }, { 0x00,0x00,0xff,0xff }, | |
+ { 0x00,0x00,0xbf,0xff }, { 0x47,0x2b,0xbf,0xff }, | |
+ { 0x97,0x00,0x87,0xff }, { 0xab,0x00,0x23,0xff }, | |
+ { 0xab,0x13,0x00,0xff }, { 0x8b,0x17,0x00,0xff }, | |
+ { 0x53,0x30,0x00,0xff }, { 0x00,0x78,0x00,0xff }, | |
+ { 0x00,0x6b,0x00,0xff }, { 0x00,0x5b,0x00,0xff }, | |
+ { 0x00,0x43,0x58,0xff }, { 0x00,0x00,0x00,0xff }, | |
+ { 0x00,0x00,0x00,0xff }, { 0x00,0x00,0x00,0xff }, | |
+ { 0xbf,0xbf,0xbf,0xff }, { 0x00,0x78,0xF8,0xff }, | |
+ { 0x00,0x58,0xf8,0xff }, { 0x6b,0x47,0xff,0xff }, | |
+ { 0xdb,0x00,0xcd,0xff }, { 0xe7,0x00,0x5b,0xff }, | |
+ { 0xf8,0x38,0x00,0xff }, { 0xe7,0x5f,0x13,0xff }, | |
+ { 0xaf,0x7f,0x00,0xff }, { 0x00,0xb8,0x00,0xff }, | |
+ { 0x00,0xab,0x00,0xff }, { 0x00,0xab,0x47,0xff }, | |
+ { 0x00,0x8b,0x8b,0xff }, { 0x00,0x00,0x00,0xff }, | |
+ { 0x00,0x00,0x00,0xff }, { 0x00,0x00,0x00,0xff }, | |
+ { 0xf8,0xf8,0xf8,0xff }, { 0x3f,0xbf,0xff,0xff }, | |
+ { 0x6b,0x88,0xff,0xff }, { 0x98,0x78,0xf8,0xff }, | |
+ { 0xf8,0x78,0xf8,0xff }, { 0xf8,0x58,0x98,0xff }, | |
+ { 0xf8,0x78,0x58,0xff }, { 0xff,0xa3,0x47,0xff }, | |
+ { 0xf8,0xb8,0x00,0xff }, { 0xb8,0xf8,0x18,0xff }, | |
+ { 0x5b,0xdb,0x57,0xff }, { 0x58,0xf8,0x98,0xff }, | |
+ { 0x00,0xeb,0xdb,0xff }, { 0x78,0x78,0x78,0xff }, | |
+ { 0x00,0x00,0x00,0xff }, { 0x00,0x00,0x00,0xff }, | |
+ { 0xff,0xff,0xff,0xff }, { 0xa7,0xe7,0xff,0xff }, | |
+ { 0xb8,0xb8,0xf8,0xff }, { 0xd8,0xb8,0xf8,0xff }, | |
+ { 0xf8,0xb8,0xf8,0xff }, { 0xfb,0xa7,0xc3,0xff }, | |
+ { 0xf0,0xd0,0xb0,0xff }, { 0xff,0xe3,0xab,0xff }, | |
+ { 0xfb,0xdb,0x7b,0xff }, { 0xd8,0xf8,0x78,0xff }, | |
+ { 0xb8,0xf8,0xb8,0xff }, { 0xb8,0xf8,0xd8,0xff }, | |
+ { 0x00,0xff,0xff,0xff }, { 0xf8,0xd8,0xf8,0xff }, | |
+ { 0x00,0x00,0x00,0xff }, { 0x00,0x00,0x00,0xff }, | |
+}; | |
+ | |
+#endif | |
diff --git a/src/WeeNESWin.cpp b/src/WeeNESWin.cpp | |
new file mode 100644 | |
index 0000000..82ac4b3 | |
--- /dev/null | |
+++ b/src/WeeNESWin.cpp | |
@@ -0,0 +1,133 @@ | |
+/* | |
+** BeNES - Nintendo Entertaiment System Emulator for BeOS | |
+** | |
+** * 1999 by makoto yamagata | |
+** | |
+** This program is free software; you can redistribute it and/or modify | |
+** it under the terms of the GNU General Public License as published by | |
+** the Free Software Foundation; either version 2 of the License, or | |
+** (at your option) any later version. | |
+** | |
+** This program is distributed in the hope that it will be useful, | |
+** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+** GNU General Public License for more details. | |
+** | |
+** You should have received a copy of the GNU General Public License | |
+** along with this program; if not, write to the Free Software | |
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
+*/ | |
+#include <app/Application.h> | |
+#include <app/Message.h> | |
+#include <interface/Screen.h> | |
+#include <cstring> | |
+ | |
+#include "WeeNESPalette.h" | |
+#include "WeeNESWin.h" | |
+#include "WeeNESMenu.h" | |
+ | |
+//-------------------------------------------------------------------------- | |
+WeeNESWin::WeeNESWin(): | |
+ BWindow(BRect(X, Y, X+W, Y+H), | |
+ "WeeNES", | |
+ B_TITLED_WINDOW, | |
+ B_NOT_RESIZABLE), | |
+ mOffscreen(NULL), | |
+ mView(NULL), | |
+ mMenubar(NULL), | |
+ mFrameSnooze(0) | |
+{ | |
+ Lock(); | |
+ mMenubar = WeeNESMenu::Build(); | |
+ AddChild(mMenubar); | |
+ BRect barFrame(mMenubar->Frame()); | |
+ | |
+ ResizeTo(W, H+barFrame.Height()); | |
+ | |
+ mView = new BView(BRect(0, 0, W, H), NULL, B_FOLLOW_ALL, 0); | |
+ AddChild(mView); | |
+ mView->MoveBy(0, barFrame.Height()+1); | |
+ mView->SetViewColor(0, 0, 0); | |
+ | |
+ mOffscreen = new BBitmap(BRect(0, 0, W-1, H-1), B_COLOR_8_BIT); | |
+ mBits = static_cast<uchar*>(mOffscreen->Bits()); | |
+ mBytesPerRow = mOffscreen->BytesPerRow(); | |
+ BScreen* screen = new BScreen(this); | |
+ memset(mBits, screen->IndexForColor(0, 0, 0, 255), W*H); | |
+ for (int i=0; i<64; i++) { | |
+ IndexPalette[i] = screen->IndexForColor(WeeNESPalette[i]); | |
+ } | |
+ delete screen; | |
+ Unlock(); | |
+} | |
+ | |
+//-------------------------------------------------------------------------- | |
+BMenu* WeeNESWin::getSkipFramesMenu() | |
+{ | |
+ BMenu* menu = mMenubar->SubmenuAt(1)->SubmenuAt(0); | |
+ return menu; | |
+} | |
+ | |
+//-------------------------------------------------------------------------- | |
+BMenu* WeeNESWin::getFramesParSecMenu() | |
+{ | |
+ BMenu* menu = mMenubar->SubmenuAt(1)->SubmenuAt(1); | |
+ return menu; | |
+} | |
+ | |
+//-------------------------------------------------------------------------- | |
+BMenu* WeeNESWin::getSoundMenu() | |
+{ | |
+ BMenu* menu = mMenubar->SubmenuAt(1)->SubmenuAt(2); | |
+ return menu; | |
+} | |
+ | |
+//-------------------------------------------------------------------------- | |
+BMenu* WeeNESWin::getInputMenu() | |
+{ | |
+ BMenu* menu = mMenubar->SubmenuAt(1)->SubmenuAt(3); | |
+ return menu; | |
+} | |
+ | |
+//-------------------------------------------------------------------------- | |
+void WeeNESWin::setFPS(int fps) | |
+{ | |
+ if (fps) { | |
+ mFrameSnooze = 1000000 / fps; | |
+ } | |
+ else { | |
+ mFrameSnooze = 0; | |
+ } | |
+} | |
+ | |
+//-------------------------------------------------------------------------- | |
+bool WeeNESWin::QuitRequested() | |
+{ | |
+ be_app->PostMessage(B_QUIT_REQUESTED, be_app); | |
+ return true; | |
+} | |
+ | |
+//-------------------------------------------------------------------------- | |
+void WeeNESWin::updateScreen(const NesVirtualScreen* screen, bool draw) | |
+{ | |
+ static bigtime_t prevTime = 0; | |
+ if (draw) { | |
+ static const int Y_MIN = NesDisplay::VisibleTop; | |
+ static const int Y_MAX = NesDisplay::VisibleBottom; | |
+ | |
+ for (int y=Y_MIN; y<=Y_MAX; y++) { | |
+ for (int x=8; x<256-8; x++) { | |
+ *(mBits+(y*mBytesPerRow)+x) = | |
+ IndexPalette[screen->bits[y][x]]; | |
+ } | |
+ } | |
+ Lock(); | |
+ mView->DrawBitmap(mOffscreen); | |
+ Unlock(); | |
+ } | |
+ bigtime_t snooze_time = mFrameSnooze - (system_time()-prevTime); | |
+ if (snooze_time > 0) { | |
+ snooze(snooze_time); | |
+ } | |
+ prevTime = system_time(); | |
+} | |
diff --git a/src/WeeNESWin.h b/src/WeeNESWin.h | |
new file mode 100644 | |
index 0000000..9039e19 | |
--- /dev/null | |
+++ b/src/WeeNESWin.h | |
@@ -0,0 +1,52 @@ | |
+/* | |
+** BeNES - Nintendo Entertaiment System Emulator for BeOS | |
+** | |
+** * 1999 by makoto yamagata | |
+** | |
+** This program is free software; you can redistribute it and/or modify | |
+** it under the terms of the GNU General Public License as published by | |
+** the Free Software Foundation; either version 2 of the License, or | |
+** (at your option) any later version. | |
+** | |
+** This program is distributed in the hope that it will be useful, | |
+** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+** GNU General Public License for more details. | |
+** | |
+** You should have received a copy of the GNU General Public License | |
+** along with this program; if not, write to the Free Software | |
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
+*/ | |
+#ifndef BENESWIN_H_DEFINED | |
+#define BENESWIN_H_DEFINED | |
+ | |
+#include <interface/Window.h> | |
+#include <interface/Menu.h> | |
+#include <interface/Bitmap.h> | |
+#include "NesDisplay.h" | |
+#include "NesJoypad.h" | |
+ | |
+class WeeNESWin: public BWindow, | |
+ public NesDisplay { | |
+ BBitmap* mOffscreen; | |
+ BView* mView; | |
+ uint32 IndexPalette[256]; | |
+ enum { X=100, Y=100, W=256, H=240 }; | |
+ uchar* mBits; | |
+ int mBytesPerRow; | |
+ BMenuBar* mMenubar; | |
+ bigtime_t mFrameSnooze; | |
+public: | |
+ WeeNESWin(); | |
+ bool QuitRequested(); | |
+ BMenuBar* getMenubar() { return mMenubar; } | |
+ BMenu* getSkipFramesMenu(); | |
+ BMenu* getFramesParSecMenu(); | |
+ BMenu* getSoundMenu(); | |
+ BMenu* getInputMenu(); | |
+ void updateScreen(const NesVirtualScreen* screen, bool draw); | |
+ void setFPS(int fps); | |
+ void clear() { Lock(); mView->Invalidate(); Unlock(); } | |
+}; | |
+ | |
+#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment