Unverified Commit ea6ad94f authored by Ignacio Sanchez Gines's avatar Ignacio Sanchez Gines
Browse files

Merge branch 'develop'

parents d2bede9a 4de912fc
# Netbeans files
dist/
build/
private/
# Mac files
*.DS_Store
*.dylib
*.app/
# Visual Studio files
.vscode/
.vs/
ipch/
[Oo]bj
......@@ -57,7 +54,8 @@ desktop.ini
*.gearsystem
*.so
*.sav
*.state
*.tmp
*.state*
# Qt Ignores
moc_*.cpp
......@@ -73,11 +71,10 @@ Gearsystem.pro.user.*
xcuserdata/
*.xcexplist
*.xcsettings
*.xccheckout
#rpi
platforms/raspberry*/**/gearsystem
#binaries
platforms/**/gearsystem
#Switch
*.a
......
matrix:
language: cpp
jobs:
include:
- os: linux
dist: trusty
sudo: required
language: cpp
env: BUILD_TYPE=desktop
- os: linux
dist: trusty
sudo: required
language: cpp
env: BUILD_TYPE=libretro
- os: osx
language: cpp
env: BUILD_TYPE=ios
- os: linux
dist: bionic
env: BUILD_TYPE=Linux
- os: linux
dist: bionic
env: BUILD_TYPE=Libretro
- os: osx
env: BUILD_TYPE=iOS
- os: osx
env: BUILD_TYPE=macOS
before_install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu $(lsb_release -sc) universe"; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get update -qq; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -y build-essential qt5-default qttools5-dev-tools freeglut3-dev libsdl2-dev libglew-dev; fi
- if [[ "$BUILD_TYPE" == "Linux" ]]; then sudo apt-get install -y build-essential libsdl2-dev libglew-dev; fi
- if [[ "$BUILD_TYPE" == "macOS" ]]; then brew install sdl2; fi
script:
- if [[ "$BUILD_TYPE" == "ios" ]]; then xcodebuild clean build -sdk iphonesimulator -project platforms/ios/Gearsystem.xcodeproj -scheme Gearsystem CODE_SIGNING_REQUIRED=NO; fi
- if [[ "$BUILD_TYPE" == "desktop" ]]; then cd platforms/linux/Gearsystem && qmake Gearsystem.pro && make; fi
- if [[ "$BUILD_TYPE" == "libretro" ]]; then cd platforms/libretro && make; fi
- if [[ "$BUILD_TYPE" == "iOS" ]]; then xcodebuild clean build -sdk iphonesimulator -project platforms/ios/Gearsystem.xcodeproj -scheme Gearsystem CODE_SIGNING_REQUIRED=NO; fi
- if [[ "$BUILD_TYPE" == "Linux" ]]; then cd platforms/linux && make; fi
- if [[ "$BUILD_TYPE" == "Libretro" ]]; then cd platforms/libretro && make; fi
- if [[ "$BUILD_TYPE" == "macOS" ]]; then cd platforms/macos && make; fi
Gearsystem
=======
<b>Copyright &copy; 2013 by Ignacio Sanchez</b>
# Gearsystem
----------
[![Build Status](https://travis-ci.org/drhelius/Gearsystem.svg?branch=master)](https://travis-ci.org/drhelius/Gearsystem)
Gearsystem is a Sega Master System / Game Gear / SG-1000 emulator written in C++ that runs on iOS, Raspberry Pi, Mac, Windows, Linux and RetroArch.
Gearsystem is a cross-platform Sega Master System / Game Gear / SG-1000 emulator written in C++ that runs on iOS, Raspberry Pi, macOS, Windows, Linux and RetroArch.
Follow me on Twitter for updates: http://twitter.com/drhelius
Please, consider [sponsoring](https://github.com/sponsors/drhelius) and following me on [Twitter](https://twitter.com/drhelius) for updates.
----------
Downloads
---------
- **iOS**: Build Gearsystem with Xcode and transfer it to your device. You can open rom files from other apps like Safari or Dropbox, or use [iTunes file sharing](http://support.apple.com/kb/ht4094).
- **Mac OS X**: <code>brew install gearsystem</code>
- **Windows**: [Gearsystem-2.6.0-Windows.zip](https://github.com/drhelius/Gearsystem/releases/download/gearsystem-2.6.0/Gearsystem-2.6.0-Windows.zip) (NOTE: You may need to install the [Microsoft Visual C++ Redistributable](https://go.microsoft.com/fwlink/?LinkId=746572))
- **Linux**: [Gearsystem-2.6.0-Linux.tar.xz](https://github.com/drhelius/Gearsystem/releases/download/gearsystem-2.6.0/Gearsystem-2.6.0-Linux.tar.xz)
## Downloads
- **Windows**: [Gearsystem-3.0.0-Windows.zip](https://github.com/drhelius/Gearsystem/releases/download/gearsystem-3.0.0/Gearsystem-3.0.0-Windows.zip)
- NOTE: You may need to install the [Microsoft Visual C++ Redistributable](https://go.microsoft.com/fwlink/?LinkId=746572)
- **macOS**:
- `brew cask install gearsystem`
- Or install manually: [Gearsystem-3.0.0-macOS.zip](https://github.com/drhelius/Gearsystem/releases/download/gearsystem-3.0.0/Gearsystem-3.0.0-macOS.zip)
- **Linux**: [Gearsystem-3.0.0-Linux.tar.xz](https://github.com/drhelius/Gearsystem/releases/download/gearsystem-3.0.0/Gearsystem-3.0.0-Linux.tar.xz)
- **iOS**: Build Gearsystem with Xcode and transfer it to your device. You can open rom files from other apps like Safari or Dropbox, or use your iCloud Drive.
- **RetroArch**: [Libretro core documentation](https://docs.libretro.com/library/gearsystem/).
- **Raspberry Pi**: Build Gearsystem from sources. Optimized projects are provided for Raspberry Pi 1, 2, 3 and 4.
- **Raspberry Pi**: Build Gearsystem from sources. Optimized projects are provided for Raspberry Pi 1, 2 and 3.
## Supported Machines
Supported Machines
------------------
- Sega Mark III
- Sega Master System
- Sega Game Gear
- Sega Game 1000 (SG-1000)
- Othello Multivision
Features
--------
- Highly accurate Z80 core, including undocumented opcodes and behaviour like R and [MEMPTR](https://gist.github.com/drhelius/8497817) registers.
## Features
- Accurate Z80 core, including undocumented opcodes and behaviour like R and [MEMPTR](https://gist.github.com/drhelius/8497817) registers.
- Multi-Mapper support: SEGA, Codemasters, Korean, SG-1000, and ROM only cartridges.
- External RAM support with save files.
- Automatic region detection: NTSC-JAP, NTSC-USA, PAL-EUR.
- Highly accurate VDP emulation including timing and SMS2 only 224 mode support.
- Accurate VDP emulation including timing and SMS2 only 224 mode support.
- Internal database for rom detection.
- Audio emulation using SDL Audio and [Sms_Snd_Emu library](http://blargg.8bitalley.com/libs/audio.html#Sms_Snd_Emu).
- Saves battery powered RAM cartridges to file.
- Save states.
- Integrated disassembler. It can dump the full disassembled memory to a text file or access it in real time.
- Compressed rom support (ZIP deflate).
- Game Genie and Pro Action Replay cheat support.
- Multi platform. Runs on Windows, Linux, Mac OS X, Raspberry Pi, iOS and as a libretro core (RetroArch).
- Supported platforms: Windows, Linux, macOS, Raspberry Pi, iOS and RetroArch (libretro).
## Build Instructions
### Windows
- You need Microsoft Visual Studio Community 2019 or later.
- Open the Gearsystem Visual Studio solution `platforms/windows/Gearsystem.sln` and build.
- You may want to use the `platforms/windows/Makefile` to build the application using MinGW.
Build Instructions
------------------
### macOS
- Install Xcode and run `xcode-select --install` in the terminal for the compiler to be available on the command line.
- Run this commands to generate a Mac *app* bundle:
``` shell
brew install sdl2
cd platforms/macos
make dist
```
### Linux
- Ubuntu / Debian:
``` shell
sudo apt-get install build-essential libsdl2-dev libglew-dev
cd platforms/linux
make
```
- Fedora:
``` shell
sudo dnf install @development-tools gcc-c++ SDL2-devel glew-devel
cd platforms/linux
make
```
### iOS
- Install Xcode for Mac OS X. You need iOS SDK 8 or later.
- Build the project <code>platforms/ios/Gearsystem.xcodeproj</code>
- Run it on real hardware using your iOS developer certificate. Make sure it builds on Release for better performance.
### Raspberry Pi - Raspbian
- Install Xcode for macOS. You need iOS 13 SDK or later.
- Build the project `platforms/ios/Gearsystem.xcodeproj`
- Run it on real hardware using your iOS developer certificate. Make sure it builds on *Release* for better performance.
### Libretro
- Ubuntu / Debian:
``` shell
sudo apt-get install build-essential
cd platforms/libretro
make
```
- Fedora:
``` shell
sudo dnf install @development-tools gcc-c++
cd platforms/libretro
make
```
### Raspberry Pi 2 & 3 - Raspbian
- Install and configure [SDL 2](http://www.libsdl.org/download-2.0.php) for development:
``` shell
sudo apt-get update
sudo apt-get upgrade
......@@ -66,50 +120,14 @@ cd SDL2-2.0.9 && mkdir build && cd build
make -j 4
sudo make install
```
- Install libconfig library dependencies for development: <code>sudo apt-get install libconfig++-dev</code>.
- Run <code>make -j 4</code> in the proper folder for your Raspberry Pi version:
- <code>platforms/raspberrypi/</code>
- <code>platforms/raspberrypi2/</code>
- <code>platforms/raspberrypi3/x86/</code>
- <code>platforms/raspberrypi3/x64/</code>
- <code>platforms/raspberrypi4/</code>
- Use <code>export SDL_AUDIODRIVER=ALSA</code> before running the emulator for the best performance.
- Gearsystem generates a <code>gearsystem.cfg</code> configuration file where you can customize keyboard and gamepads. Key codes are from [SDL](https://wiki.libsdl.org/SDL_Keycode).
### Windows
- You need Visual Studio 2017 or later.
- Install the [Qt 5 Open Source SDK for Windows](https://www.qt.io/download/).
- Install the [QtVisualStudioTools Extension](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools-19123) and point it to the Qt SDK.
- Open the Gearsystem Visual Studio solution <code>platforms/windows/Gearsystem/Gearsystem.sln</code> and build.
### Mac OS X
- You need Qt Creator, included in the Qt 5 SDK.
- Install Xcode and run <code>xcode-select --install</code> in the terminal for the compiler to be available on the command line.
- Install the [Qt 5 SDK for Mac OS](https://www.qt.io/download/).
- Download [SDL 2](http://www.libsdl.org/download-2.0.php) source code. Then run this commands:
``` shell
./configure
make
sudo make install
```
- Open the <code>platforms/macosx/Gearsystem/Gearsystem.pro</code> project file with Qt Creator and build.
- Install libconfig library dependencies for development: `sudo apt-get install libconfig++-dev`
- Use `make -j 4` in the `platforms/raspberrypi3/x64/` folder to build the project.
- Use `export SDL_AUDIODRIVER=ALSA` before running the emulator for the best performance.
- Gearsystem generates a `gearsystem.cfg` configuration file where you can customize keyboard and gamepads. Key codes are from [SDL](https://wiki.libsdl.org/SDL_Keycode).
### Linux
- Ubuntu / Debian:
``` shell
sudo apt-get install build-essential qt5-default qttools5-dev-tools freeglut3-dev libsdl2-dev libglew-dev
cd platforms/linux/Gearsystem
qmake Gearsystem.pro && make
```
- Fedora:
``` shell
sudo dnf install @development-tools gcc-c++ qt5-devel freeglut-devel SDL2-devel glew-devel
cd platforms/linux/Gearsystem
qmake-qt5 Gearsystem.pro && make
```
Accuracy Tests
--------------
## Accuracy Tests
Zexall Z80 instruction exerciser ([from SMS Power!](http://www.smspower.org/Homebrew/ZEXALL-SMS))
......@@ -121,8 +139,7 @@ SMS VDP Test ([from SMS Power!](http://www.smspower.org/Homebrew/SMSVDPTest-SMS
![vdptest.sms](http://www.geardome.com/files/gearsystem/vdptest5.png)![vdptest.sms](http://www.geardome.com/files/gearsystem/vdptest4.png)![vdptest.sms](http://www.geardome.com/files/gearsystem/vdptest6.png)
Screenshots
-----------
## Screenshots
![Screenshot](http://www.geardome.com/files/gearsystem/01.png)![Screenshot](http://www.geardome.com/files/gearsystem/02.png)
![Screenshot](http://www.geardome.com/files/gearsystem/03.png)![Screenshot](http://www.geardome.com/files/gearsystem/04.png)
......@@ -134,22 +151,6 @@ Screenshots
<img src="http://www.geardome.com/files/gearsystem/15.png" width="368" height="326"><img src="http://www.geardome.com/files/gearsystem/16.png" width="368" height="326">
<img src="http://www.geardome.com/files/gearsystem/17.png" width="368" height="326"><img src="http://www.geardome.com/files/gearsystem/18.png" width="368" height="326">
License
-------
<i>Gearsystem - Sega Master System / Game Gear Emulator</i>
<i>Copyright (C) 2013 Ignacio Sanchez</i>
<i>This program is free software: you can redistribute it and/or modify</i>
<i>it under the terms of the GNU General Public License as published by</i>
<i>the Free Software Foundation, either version 3 of the License, or</i>
<i>any later version.</i>
<i>This program is distributed in the hope that it will be useful,</i>
<i>but WITHOUT ANY WARRANTY; without even the implied warranty of</i>
<i>MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</i>
<i>GNU General Public License for more details.</i>
## License
<i>You should have received a copy of the GNU General Public License</i>
<i>along with this program. If not, see http://www.gnu.org/licenses/</i>
Gearsystem is licensed under the GNU General Public License v3.0 License, see [LICENSE](LICENSE) for more information.
......@@ -5,6 +5,7 @@
#include <assert.h>
#include <string.h>
#include <string>
/* Copyright (C) 2005 by Shay Green. Permission is hereby granted, free of
charge, to any person obtaining a copy of this software module and associated
......@@ -35,6 +36,20 @@ Sound_Queue::Sound_Queue()
bufs = NULL;
free_sem = NULL;
sound_open = false;
sync_output = true;
std::string platform = SDL_GetPlatform();
if (platform == "Linux")
{
SDL_InitSubSystem(SDL_INIT_AUDIO);
SDL_AudioInit("alsa");
}
else
{
SDL_Init(SDL_INIT_AUDIO);
}
atexit(SDL_Quit);
}
Sound_Queue::~Sound_Queue()
......@@ -45,20 +60,23 @@ Sound_Queue::~Sound_Queue()
const char* Sound_Queue::start( long sample_rate, int chan_count )
{
assert( !bufs ); // can only be initialized once
write_buf = 0;
write_pos = 0;
read_buf = 0;
bufs = new sample_t [(long) buf_size * buf_count];
if ( !bufs )
return "Out of memory";
currently_playing_ = bufs;
for (long l = 0; l < ((long) buf_size * buf_count); l++)
bufs[0] = 0;
free_sem = SDL_CreateSemaphore( buf_count - 1 );
if ( !free_sem )
return sdl_error( "Couldn't create semaphore" );
SDL_AudioSpec as;
as.freq = (int)sample_rate;
as.format = AUDIO_S16SYS;
......@@ -72,7 +90,7 @@ const char* Sound_Queue::start( long sample_rate, int chan_count )
return sdl_error( "Couldn't open SDL audio" );
SDL_PauseAudio( false );
sound_open = true;
return NULL;
}
......@@ -84,13 +102,13 @@ void Sound_Queue::stop()
SDL_PauseAudio( true );
SDL_CloseAudio();
}
if ( free_sem )
{
SDL_DestroySemaphore( free_sem );
free_sem = NULL;
}
delete [] bufs;
bufs = NULL;
}
......@@ -107,36 +125,42 @@ inline Sound_Queue::sample_t* Sound_Queue::buf( int index )
return bufs + (long) index * buf_size;
}
void Sound_Queue::write( const sample_t* in, int count )
void Sound_Queue::write( const sample_t* in, int count, bool sync )
{
sync_output = sync;
while ( count )
{
int n = buf_size - write_pos;
if ( n > count )
n = count;
memcpy( buf( write_buf ) + write_pos, in, n * sizeof (sample_t) );
in += n;
write_pos += n;
count -= n;
if ( write_pos >= buf_size )
{
write_pos = 0;
write_buf = (write_buf + 1) % buf_count;
SDL_SemWait( free_sem );
if (sync_output)
SDL_SemWait( free_sem );
}
}
}
void Sound_Queue::fill_buffer( Uint8* out, int count )
{
if ( SDL_SemValue( free_sem ) < buf_count - 1 )
if ((SDL_SemValue( free_sem ) < buf_count - 1 ) || !sync_output)
{
currently_playing_ = buf( read_buf );
memcpy( out, buf( read_buf ), count );
read_buf = (read_buf + 1) % buf_count;
SDL_SemPost( free_sem );
if (sync_output)
SDL_SemPost( free_sem );
}
else
{
......
......@@ -13,24 +13,24 @@ class Sound_Queue {
public:
Sound_Queue();
~Sound_Queue();
// Initialize with specified sample rate and channel count.
// Returns NULL on success, otherwise error string.
const char* start( long sample_rate, int chan_count = 1 );
// Number of samples in buffer waiting to be played
int sample_count() const;
// Write samples to buffer and block until enough space is available
typedef short sample_t;
void write( const sample_t*, int count );
void write( const sample_t*, int count, bool sync = true );
// Pointer to samples currently playing (for showing waveform display)
sample_t const* currently_playing() const { return currently_playing_; }
// Stop audio output
void stop();
private:
enum { buf_size = 2048 };
enum { buf_count = 3 };
......@@ -41,7 +41,8 @@ private:
int write_buf;
int write_pos;
bool sound_open;
bool sync_output;
sample_t* buf( int index );
void fill_buffer( Uint8*, int );
static void fill_buffer_( void*, Uint8*, int );
......
This diff is collapsed.
This diff is collapsed.
#ifndef IMGUIFILEBROWSER_H
#define IMGUIFILEBROWSER_H
#include <string>
#include <vector>
#include "../imgui/imgui.h"
namespace imgui_addons
{
class ImGuiFileBrowser
{
public:
ImGuiFileBrowser();
~ImGuiFileBrowser();
enum class DialogMode
{
SELECT, //Select Directory Mode
OPEN, //Open File mode
SAVE //Save File mode.
};
/* Use this to show an open file dialog. The function takes label for the window,
* the size, a DialogMode enum value defining in which mode the dialog should operate and optionally the extensions that are valid for opening.
* Note that the select directory mode doesn't need any extensions.
*/
bool showFileDialog(const std::string& label, const DialogMode mode, const ImVec2& sz_xy = ImVec2(0,0), const std::string& valid_types = "*.*", bool* is_open = 0);
/* Store the opened/saved file name or dir name (incase of selectDirectoryDialog) and the absolute path to the selection
* Should only be accessed when above functions return true else may contain garbage.
*/
std::string selected_fn;
std::string selected_path;
std::string ext; // Store the saved file extension
private:
struct Info
{
Info(std::string name, bool is_hidden) : name(name), is_hidden(is_hidden)
{
}
std::string name;
bool is_hidden;
};
//Enum used as bit flags.
enum FilterMode
{
FilterMode_Files = 0x01,
FilterMode_Dirs = 0x02
};
//Helper Functions
static std::string wStringToString(const wchar_t* wchar_arr);
static bool alphaSortComparator(const Info& a, const Info& b);
ImVec2 getButtonSize(std::string button_text);
/* Helper Functions that render secondary modals
* and help in validating file extensions and for filtering, parsing top navigation bar.
*/
void setValidExtTypes(const std::string& valid_types_string);
bool validateFile();
void showErrorModal();
void showInvalidFileModal();
bool showReplaceFileModal();
void showHelpMarker(std::string desc);
void parsePathTabs(std::string str);
void filterFiles(int filter_mode);
/* Core Functions that render the 4 different regions making up
* a simple file dialog
*/
bool renderNavAndSearchBarRegion();
bool renderFileListRegion();
bool renderInputTextAndExtRegion();
bool renderButtonsAndCheckboxRegion();
bool renderInputComboBox();
void renderExtBox();
/* Core Functions that handle navigation and
* reading directories/files
*/
bool readDIR(std::string path);
bool onNavigationButtonClick(int idx);
bool onDirClick(int idx);
// Functions that reset state and/or clear file list when reading new directory
void clearFileList();
void closeDialog();
#if defined (WIN32) || defined (_WIN32) || defined (__WIN32)
bool loadWindowsDrives(); // Helper Function for Windows to load Drive Letters.
#endif
#if defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__)
void initCurrentPath(); // Helper function for UNIX based system to load Absolute path using realpath
#endif
ImVec2 min_size, max_size, input_combobox_pos, input_combobox_sz;
DialogMode dialog_mode;
int filter_mode, col_items_limit, selected_idx, selected_ext_idx;
float col_width, ext_box_width;
bool show_hidden, show_inputbar_combobox, is_dir, is_appearing, filter_dirty, validate_file;
char input_fn[256];
bool* is_open_;
std::vector<std::string> valid_exts;
std::vector<std::string> current_dirlist;
std::vector<Info> subdirs;
std::vector<Info> subfiles;
std::string current_path, error_msg, error_title, invfile_modal_id, repfile_modal_id;
ImGuiTextFilter filter;
std::string valid_types;
std::vector<Info> filtered_dirs; // Note: We don't need to call delete. It's just for storing filtered items from subdirs and subfiles so we don't use PassFilter every frame.
std::vector<Info> filtered_files;
std::vector< std::reference_wrapper<std::string> > inputcb_filter_files;
};
}
#endif // IMGUIFILEBROWSER_H
CXX = g++
#CXX = clang++
EXE = gearsystem
GIT_VERSION := "$(shell git describe --abbrev=4 --dirty --always --tags)"
EMULATOR_SRC=../../src
EMULATOR_DESKTOP_SHARED_SRC=../desktop-shared
EMULATOR_AUDIO_SRC=$(EMULATOR_SRC)/audio
EMULATOR_AUDIO_SHARED_SRC=../audio-shared
IMGUI_SRC=$(EMULATOR_DESKTOP_SHARED_SRC)/imgui
IMGUI_FILEBROWSER_SRC=$(EMULATOR_DESKTOP_SHARED_SRC)/FileBrowser
SOURCES = $(EMULATOR_DESKTOP_SHARED_SRC)/main.cpp $(EMULATOR_DESKTOP_SHARED_SRC)/emu.cpp $(EMULATOR_DESKTOP_SHARED_SRC)/gui.cpp $(EMULATOR_DESKTOP_SHARED_SRC)/application.cpp $(EMULATOR_DESKTOP_SHARED_SRC)/config.cpp $(EMULATOR_DESKTOP_SHARED_SRC)/renderer.cpp