Skip to content

Instantly share code, notes, and snippets.

@kallisti5
Created January 19, 2015 13:56
Show Gist options
  • Save kallisti5/86188b9fc6309ba085e7 to your computer and use it in GitHub Desktop.
Save kallisti5/86188b9fc6309ba085e7 to your computer and use it in GitHub Desktop.
benes-haiku patch
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