29 Commits

Author SHA1 Message Date
Godzil
a89e253d9c Now use glfw/OpenGL for displaying.
Code is a bit crude, but the whole emulator would need a proper refactor at some point anyway.
2021-04-04 20:55:40 +01:00
Godzil
88468d6028 Now build without SDL
But of course, display nothing.
2020-12-12 19:28:21 +00:00
Godzil
875f0edb46 printf can be a pain at time. 2020-11-14 20:30:09 +00:00
Godzil
8bd2170f44 Remove some of the Rotation code.
And add a call placeholder for read_key for now to make the compiler happy.
2020-11-14 20:28:31 +00:00
Godzil
564e0ea2e6 Remove more SDL references 2020-11-14 20:27:58 +00:00
Godzil
8976d4363f Remove SDLptc.h, the "Console" class and related code. 2020-11-14 20:27:25 +00:00
Godzil
f3aca9a3c7 Start working on implementing the video interface.
First disabling/removing all the SDL related function call/variables

Also removing some nonsensical dunction (line doubling and rotation are useless in GL mode)
2020-11-14 20:16:46 +00:00
Godzil
ece8a07dcf Remove SDL refenrence in the non working audio emulation. 2020-11-14 20:15:50 +00:00
Godzil
9035a922c3 Add GLFW in the CMakeLists, and remove all SDL references. 2020-11-14 20:14:57 +00:00
Godzil
02c16b7987 Add glfw as an external module 2020-11-14 19:36:54 +00:00
Godzil
8c79f6f417 Clang should be happy now? 2020-02-11 00:53:32 +00:00
Godzil
2802e64697 clang don't like these unused tables. 2020-02-11 00:42:33 +00:00
Godzil
e8d7d8473e GCC quirkness makes no sense sometimes. 2020-02-11 00:38:17 +00:00
Godzil
ed93d90c51 Make sure we are not forcing to GCC and add a bit of debug.
CMake find the proper lib but not the makefile? WTF
2020-02-11 00:29:34 +00:00
Godzil
6e857bf630 Stupid names ubuntu; "libsdl1.2debian", seriously? 2020-02-11 00:24:04 +00:00
Godzil
62c43f311c Trying to add SDL lib package (seems -dev don't install it) 2020-02-11 00:21:17 +00:00
Godzil
3552bb8bf9 Silly me... 2020-02-11 00:20:36 +00:00
Godzil
466f910c9a Try to also build cmake build. 2020-02-11 00:18:06 +00:00
Godzil
a5ce89d14f Hmmm it was lurking in other places! 2020-02-11 00:17:38 +00:00
Godzil
c26f935072 Interesting that not all GCC versions complain here. 2020-02-11 00:14:36 +00:00
Godzil
4967dcab21 I honestly don't care about the return value of write. 2020-02-11 00:07:16 +00:00
Godzil
a0e5006a18 Add dumpinfo to cmake, and set the CXX standard to C++98 as it should on that project. 2020-02-11 00:05:22 +00:00
Godzil
6d78199031 Update .gitignore 2020-02-11 00:04:42 +00:00
Godzil
6d5658eb68 Make gcc happy (and fix a potential issue) 2020-02-11 00:00:23 +00:00
Godzil
667f655d22 Add preliminary CMake build. Not replacing the makefile for now, will in the future. 2020-02-10 23:59:01 +00:00
Godzil
3e6f096191 Add CMake module to get Git version. 2020-02-10 23:58:18 +00:00
Godzil
0fadff165b Update travis to use latest ubuntu instead of the old 14.04 2020-02-07 18:00:54 +00:00
Godzil
cf80c9624c Add tentative travis build script 2020-02-07 17:58:12 +00:00
Godzil
b5488bacba Add portaudio for futur audio work. 2020-02-07 17:57:59 +00:00
20 changed files with 599 additions and 743 deletions

4
.gitignore vendored
View File

@@ -21,3 +21,7 @@ rom/
dumpinfo
testserial
wonderswan
# Build folder
cmake-*/
build*/

6
.gitmodules vendored Normal file
View File

@@ -0,0 +1,6 @@
[submodule "external/portaudio"]
path = external/portaudio
url = https://git.assembla.com/portaudio.git
[submodule "external/glfw"]
path = external/glfw
url = https://github.com/glfw/glfw.git

38
.travis.yml Normal file
View File

@@ -0,0 +1,38 @@
dist: bionic
language: c
os:
- linux
# - osx
#matrix:
# allow_failures:
# - os: osx
addons:
apt:
packages:
- libsdl1.2debian
- libsdl1.2-dev
compiler:
- clang
- gcc
script:
- make
- mkdir build
- cd build
- cmake ..
- make
cache:
directories:
- '$HOME/.sonar/cache'
#before_install:
# - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
# - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install glew; fi
#install: true
#after_success:
# - bash <(curl -s https://codecov.io/bash)

36
CMakeLists.txt Normal file
View File

@@ -0,0 +1,36 @@
cmake_minimum_required(VERSION 3.1)
# External cmake modules
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/external/cmake ${CMAKE_MODULE_PATH})
project("NewOswan")
include(GetGitRevisionDescription)
git_describe(VERSION --tags --dirty=-dirty)
# Include GLFW3
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
add_subdirectory("external/glfw")
find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR})
set(CMAKE_C_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-unused-result -Wno-write-strings -Werror")
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-unused-result -Wno-write-strings -Werror")
message("-- Building version ${VERSION}")
add_executable(wonderswan main.cpp)
set_property(TARGET wonderswan PROPERTY CXX_STANDARD 98)
target_compile_definitions(wonderswan PUBLIC VERSION="${VERSION}")
target_include_directories(wonderswan PUBLIC source)
add_subdirectory(source)
target_link_libraries(wonderswan wswan glfw ${OPENGL_glu_LIBRARY} ${OPENGL_gl_LIBRARY})
add_executable(dumpinfo dumpinfo.c)

View File

@@ -16,12 +16,13 @@ OBJS = $(wonderswan_CXX_SRCS:.cpp=.o)
all: wonderswan dumpinfo
CXX = g++
CXXFLAGS = -g -O2 `sdl-config --cflags` -Wall -Werror -std=c++98 -Wno-write-strings
# CXX = g++
CXXFLAGS = -g -O2 `sdl-config --cflags` -Wall -std=c++98 -Wno-write-strings -Wno-unused-result
OPTIONS = -D_REENTRANT -I. -DVERSION=\"`git describe --tags --long --dirty`\"
LIBRARY_PATH =
LIBS = -g $(LIBRARY_PATH) `sdl-config --libs`
SDL_LIBS = `sdl-config --libs`
LIBS = -g $(LIBRARY_PATH) $(SDL_LIBS)
ALLCFLAGS = $(CFLAGS) $(CEXTRA) $(OPTIONS) $(ALLFLAGS)
ALLCXXFLAGS=$(CXXFLAGS) $(CXXEXTRA) $(OPTIONS) $(ALLFLAGS)
@@ -53,4 +54,4 @@ dumpinfo: dumpinfo.o
$(CXX) $(LIBS) -o $@ $(<)
wonderswan: $(OBJS)
$(CXX) $(LIBS) -o $@ $(OBJS)
$(CXX) -o $@ $(OBJS) $(LIBS)

View File

@@ -0,0 +1,168 @@
# - Returns a version string from Git
#
# These functions force a re-configure on each git commit so that you can
# trust the values of the variables in your build system.
#
# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
#
# Returns the refspec and sha hash of the current head revision
#
# git_describe(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the source tree, and adjusting
# the output so that it tests false if an error occurs.
#
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe --exact-match on the source tree,
# and adjusting the output so that it tests false if there was no exact
# matching tag.
#
# git_local_changes(<var>)
#
# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes.
# Uses the return code of "git diff-index --quiet HEAD --".
# Does not regard untracked files.
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__get_git_revision_description)
return()
endif()
set(__get_git_revision_description YES)
# We must run the following at "include" time, not at function call time,
# to find the path to this module rather than the path to a calling list file
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
function(get_git_head_revision _refspecvar _hashvar)
set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories
set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
# We have reached the root directory, we are not in git
set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
return()
endif()
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
endwhile()
# check if this is a submodule
if(NOT IS_DIRECTORY ${GIT_DIR})
file(READ ${GIT_DIR} submodule)
string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule})
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
endif()
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
if(NOT EXISTS "${GIT_DATA}")
file(MAKE_DIRECTORY "${GIT_DATA}")
endif()
if(NOT EXISTS "${GIT_DIR}/HEAD")
return()
endif()
set(HEAD_FILE "${GIT_DATA}/HEAD")
configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
"${GIT_DATA}/grabRef.cmake"
@ONLY)
include("${GIT_DATA}/grabRef.cmake")
set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
endfunction()
function(git_describe _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
return()
endif()
# TODO sanitize
#if((${ARGN}" MATCHES "&&") OR
# (ARGN MATCHES "||") OR
# (ARGN MATCHES "\\;"))
# message("Please report the following error to the project!")
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
#endif()
#message(STATUS "Arguments to execute_process: ${ARGN}")
execute_process(COMMAND
"${GIT_EXECUTABLE}"
describe
#${hash}
${ARGN}
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var} "${out}" PARENT_SCOPE)
endfunction()
function(git_get_exact_tag _var)
git_describe(out --exact-match ${ARGN})
set(${_var} "${out}" PARENT_SCOPE)
endfunction()
function(git_local_changes _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
return()
endif()
execute_process(COMMAND
"${GIT_EXECUTABLE}"
diff-index --quiet HEAD --
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(res EQUAL 0)
set(${_var} "CLEAN" PARENT_SCOPE)
else()
set(${_var} "DIRTY" PARENT_SCOPE)
endif()
endfunction()

View File

@@ -0,0 +1,41 @@
#
# Internal file for GetGitRevisionDescription.cmake
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
set(HEAD_HASH)
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
if(HEAD_CONTENTS MATCHES "ref")
# named branch
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
else()
configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
set(HEAD_HASH "${CMAKE_MATCH_1}")
endif()
endif()
else()
# detached HEAD
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
endif()
if(NOT HEAD_HASH)
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
string(STRIP "${HEAD_HASH}" HEAD_HASH)
endif()

1
external/glfw vendored Submodule

Submodule external/glfw added at 0ef149c8f2

1
external/portaudio vendored Submodule

Submodule external/portaudio added at c5d2c51bd6

View File

@@ -15,8 +15,6 @@
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include "SDL.h"
#include "source/SDLptc.h"
#include "source/log.h"
#include "source/rom.h"
#include "source/nec/nec.h"
@@ -123,9 +121,6 @@ int ws_mk_ieppath()
int main(int argc, char *argv[])
{
atexit(SDL_Quit);
SDL_Init(SDL_INIT_TIMER);
if (!log_init(LOG_PATH))
{
printf("Warning: cannot open log file %s\n",LOG_PATH);

10
source/CMakeLists.txt Normal file
View File

@@ -0,0 +1,10 @@
set(SOURCES audio.cpp emulate.cpp gpu.cpp io.cpp log.cpp memory.cpp rom.cpp ws.cpp)
set(HEADERS audio.h emulate.h gpu.h ieeprom.h initialIo.h io.h log.h memory.h rom.h ws.h)
add_library(wswan ${SOURCES} ${HEADERS})
target_link_libraries(wswan nec_v30 glfw ${OPENGL_glu_LIBRARY} ${OPENGL_gl_LIBRARY})
target_include_directories(wswan PUBLIC .)
add_subdirectory(nec)

View File

@@ -1,314 +0,0 @@
/* Some simple emulation classes to get PTC code running on SDL */
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "SDL.h"
#define randomize() srand(time(NULL))
#define random(max) (rand()%(max))
#ifndef stricmp
#define stricmp strcasecmp
#endif
class Error
{
public:
Error(const char *message)
{
strcpy(_message, message);
}
void report(void)
{
printf("Error: %s\n", _message);
}
private:
char _message[1024];
};
class Area
{
public:
Area(int left, int top, int right, int bottom)
{
_left = left;
_top = top;
_right = right;
_bottom = bottom;
}
int left(void) const
{
return(_left);
}
int right(void) const
{
return(_right);
}
int top(void) const
{
return(_top);
}
int bottom(void) const
{
return(_bottom);
}
int width(void) const
{
return(_right-_left);
}
int height(void) const
{
return(_bottom-_top);
}
private:
int _left, _top, _right, _bottom;
};
class Format
{
public:
Format(int bpp, int maskR = 0, int maskG = 0, int maskB = 0)
{
_bpp = bpp;
_maskR = maskR;
_maskG = maskG;
_maskB = maskB;
}
Uint8 BPP(void) const
{
return(_bpp);
}
Uint32 MaskR(void) const
{
return(_maskR);
}
Uint32 MaskG(void) const
{
return(_maskG);
}
Uint32 MaskB(void) const
{
return(_maskB);
}
private:
Uint8 _bpp;
Uint32 _maskR, _maskG, _maskB;
};
class Surface
{
public:
Surface(int w, int h, const Format &format)
{
surface = SDL_AllocSurface(SDL_SWSURFACE, w, h, format.BPP(),
format.MaskR(),format.MaskG(),format.MaskB(),0);
if ( surface == NULL )
{
throw Error(SDL_GetError());
}
nupdates = 0;
is_console = 0;
}
Surface(void)
{
nupdates = 0;
is_console = 1;
}
virtual ~Surface()
{
if ( ! is_console )
{
SDL_FreeSurface(surface);
}
}
virtual int width(void)
{
return surface->w;
}
virtual int height(void)
{
return surface->h;
}
virtual int pitch(void)
{
return surface->pitch;
}
virtual void palette(int32_t *pcolors)
{
SDL_Color colors[256];
for ( int i=0; i<256; ++i )
{
colors[i].r = (pcolors[i]>>16)&0xFF;
colors[i].g = (pcolors[i]>>8)&0xFF;
colors[i].b = (pcolors[i]>>0)&0xFF;
}
SDL_SetColors(surface, colors, 0, 256);
}
virtual void *lock(void)
{
if ( SDL_MUSTLOCK(surface) )
{
while ( SDL_LockSurface(surface) < 0 )
{
SDL_Delay(10);
}
}
return (Uint8 *)surface->pixels;
}
virtual void unlock(void)
{
if ( SDL_MUSTLOCK(surface) )
{
SDL_UnlockSurface(surface);
}
}
virtual void copy(Surface &dst,
const Area &srcarea, const Area &dstarea)
{
SDL_Rect srcrect, dstrect;
srcrect.x = srcarea.left();
srcrect.y = srcarea.top();
srcrect.w = srcarea.width();
srcrect.h = srcarea.height();
dstrect.x = dstarea.left();
dstrect.y = dstarea.top();
dstrect.w = dstarea.width();
dstrect.h = dstarea.height();
SDL_BlitSurface(surface, &srcrect, dst.surface, &dstrect);
dst.updates[dst.nupdates++] = dstrect;
}
virtual void copy(Surface &dst)
{
SDL_Rect srcrect, dstrect;
srcrect.x = 0;
srcrect.y = 0;
srcrect.w = surface->w;
srcrect.h = surface->h;
dstrect.x = 0;
dstrect.y = 0;
dstrect.w = surface->w;
dstrect.h = surface->h;
SDL_LowerBlit(surface, &srcrect, dst.surface, &dstrect);
dst.updates[dst.nupdates++] = dstrect;
}
virtual void update(void)
{
SDL_UpdateRects(surface, nupdates, updates);
nupdates = 0;
}
protected:
SDL_Surface *surface;
int nupdates;
SDL_Rect updates[1]; /* Definitely increase this.. */
int is_console;
};
class Console : public Surface
{
int fullscreen;
public:
Console() : Surface()
{
fullscreen=0;
}
~Console()
{
SDL_Quit();
}
void close(void)
{
SDL_Quit();
}
void option(char *option)
{
if (!stricmp(option,"fullscreen output"))
{
fullscreen=1;
}
else if (!stricmp(option,"windowed output"))
{
fullscreen=0;
}
}
void open(const char *title, int width, int height, const Format &format)
{
uint32_t flags;
if ( SDL_InitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0 )
{
throw Error(SDL_GetError());
}
flags = (SDL_HWSURFACE|SDL_HWPALETTE);
if (fullscreen)
{
flags|=SDL_FULLSCREEN;
}
surface = SDL_SetVideoMode(width, height, 0, flags);
if ( surface == NULL )
{
throw Error(SDL_GetError());
}
SDL_WM_SetCaption(title, title);
}
int key(void)
{
SDL_Event event;
int keyevent;
keyevent = 0;
while ( SDL_PollEvent(&event) )
{
/* Real key events trigger this function */
if ( event.type == SDL_KEYDOWN )
{
keyevent = 1;
}
/* So do quit events -- let the app know about it */
if ( event.type == SDL_QUIT )
{
keyevent = 1;
}
}
return(keyevent);
}
private:
};

View File

@@ -29,8 +29,6 @@
#include "io.h"
#include "audio.h"
#include "SDL.h"
#define SNDP ws_ioRam[0x80]
#define SNDV ws_ioRam[0x88]
#define SNDSWP ws_ioRam[0x8C]
@@ -91,6 +89,7 @@ int RandData[BUFSIZEN];
int CntSwp=0;
int PcmWrPos=0;
/*
const long TblChVol[16]= // n/15 n=0~15
{
-10000,-2352,-1750,-1398,-1148,-954,-796,-662,
@@ -101,6 +100,7 @@ const long TblMainVol[4]= // 1,1/2,1/4,1/8
{
0,-602,-1204,-1806
};
*/
////////////////////////////////////////////////////////////////////////////////
// seal audio specific
@@ -142,7 +142,6 @@ void ws_audio_init(void)
ws_audio_log=0;
//ws_audio_seal_init();
ws_audio_reset();
SDL_PauseAudio(0);
}
////////////////////////////////////////////////////////////////////////////////
//

View File

@@ -19,9 +19,16 @@
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <sys/mman.h>
#include <sys/time.h>
#define GLFW_INCLUDE_GLEXT
#define GL_SILENCE_DEPRECATION
#include <GLFW/glfw3.h>
/* "Apple" fix */
#ifndef GL_TEXTURE_RECTANGLE
#define GL_TEXTURE_RECTANGLE GL_TEXTURE_RECTANGLE_EXT
#endif
#include "SDL.h"
#include "SDLptc.h"
#include "log.h"
#include "io.h"
#include "ws.h"
@@ -32,336 +39,308 @@
#include "audio.h"
#include "memory.h"
SDL_Joystick *joystick=NULL;
char app_window_title[256];
int app_gameRunning=0;
int app_terminate=0;
int app_fullscreen=0;
SDL_Event app_input_event;
int app_rotated=0;
int ws_key_esc = 0;
/* Open GL stuffs */
typedef struct GLWindow_t GLWindow;
struct KeyArray
{
uint8_t lastState;
uint8_t curState;
uint8_t debounced;
GLFWwindow *window;
};
struct GLWindow_t
{
struct KeyArray keyArray[512];
GLFWwindow *windows;
uint8_t *videoMemory;
GLuint videoTexture;
int WIDTH;
int HEIGHT;
};
static GLWindow mainWindow;
static int window_num = 0;
static void ShowScreen(GLWindow *g, int w, int h)
{
glBindTexture(GL_TEXTURE_RECTANGLE, g->videoTexture);
// glTexSubImage2D is faster when not using a texture range
glTexSubImage2D(GL_TEXTURE_RECTANGLE, 0, 0, 0, w, h,
GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, g->videoMemory);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(-1.0f, 1.0f);
glTexCoord2f(0.0f, h);
glVertex2f(-1.0f, -1.0f);
glTexCoord2f(w, h);
glVertex2f(1.0f, -1.0f);
glTexCoord2f(w, 0.0f);
glVertex2f(1.0f, 1.0f);
glEnd();
glFlush();
}
static void GLWindowInitEx(GLWindow *g, int w, int h)
{
g->WIDTH = w;
g->HEIGHT = h;
g->videoTexture = window_num++;
}
static void setupGL(GLWindow *g, int w, int h)
{
g->videoMemory = (uint8_t *)malloc(w * h * sizeof(uint16_t));
memset(g->videoMemory, 0, w * h * sizeof(uint16_t));
//Tell OpenGL how to convert from coordinates to pixel values
glViewport(0, 0, w, h);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glClearColor(1.0f, 0.f, 1.0f, 1.0f);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_RECTANGLE);
glBindTexture(GL_TEXTURE_RECTANGLE, g->videoTexture);
// glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_NV_EXT, 0, NULL);
// glTexParameteri(GL_TEXTURE_RECTANGLE_NV_EXT, GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_CACHED_APPLE);
// glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, g->videoMemory);
glDisable(GL_DEPTH_TEST);
}
void restoreGL(GLWindow *g)
{
//Tell OpenGL how to convert from coordinates to pixel values
glViewport(0, 0, g->WIDTH, g->HEIGHT);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glClearColor(1.0f, 0.f, 1.0f, 1.0f);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_RECTANGLE);
glDisable(GL_DEPTH_TEST);
}
static void kbHandler(GLFWwindow *window, int key, int scan, int action, int mod)
{
struct KeyArray *keyArray;
keyArray = (struct KeyArray *)glfwGetWindowUserPointer(window);
keyArray[key].lastState = keyArray[key].curState;
if (action == GLFW_RELEASE)
{
keyArray[key].curState = GLFW_RELEASE;
}
else
{
keyArray[key].curState = GLFW_PRESS;
}
keyArray[key].debounced |= (keyArray[key].lastState == GLFW_RELEASE) && (keyArray[key].curState == GLFW_PRESS);
keyArray[key].window = window;
/*printf("key:%d, state:%d debounce:%d, laststate:%d\n", key, keyArray[key].curState,
keyArray[key].debounced, keyArray[key].lastState);*/
}
static void sizeHandler(GLFWwindow *window, int xs, int ys)
{
glfwMakeContextCurrent(window);
glViewport(0, 0, xs, ys);
ShowScreen(&mainWindow, 244, 144);
}
static void error_callback(int error, const char *description)
{
puts(description);
}
static void initDisplay(GLWindow *g)
{
int h = g->HEIGHT;
int w = g->WIDTH;
/// Initialize GLFW
glfwInit();
glfwSetErrorCallback(error_callback);
// Open screen OpenGL window
if (!(g->windows = glfwCreateWindow(g->WIDTH, g->HEIGHT, "Main", NULL, NULL)))
{
glfwTerminate();
fprintf(stderr, "Window creation error...\n");
abort();
}
glfwSetWindowAspectRatio(g->windows, 244, 144);
glfwMakeContextCurrent(g->windows);
setupGL(g, g->WIDTH, g->HEIGHT);
glfwSwapInterval(1); // We need vsync
glfwGetWindowSize(g->windows, &w, &h);
glfwSetWindowUserPointer(g->windows, g->keyArray);
glfwSetKeyCallback(g->windows, kbHandler);
glfwSetWindowSizeCallback(g->windows, sizeHandler);
}
static void clearScreen(GLWindow *g)
{
memset(g->videoMemory, 0, sizeof(uint8_t) * g->WIDTH * g->HEIGHT * 4);
}
static void updateScreen(GLWindow *g)
{
/* Update windows code */
glfwMakeContextCurrent(g->windows);
ShowScreen(g, g->WIDTH, g->HEIGHT);
glfwSwapBuffers(g->windows);
glfwPollEvents();
}
uint64_t getTicks()
{
struct timeval curTime;
uint64_t ticks;
/* Get datetime */
gettimeofday(&curTime, NULL);
ticks = (curTime.tv_sec* 1000) + curTime.tv_usec / 1000;
return ticks;
}
static inline int getKeyState(int key)
{
return mainWindow.keyArray[key].curState;
}
static void read_keys()
{
static int testJoystick=1;
ws_key_start=0;
ws_key_x4=0;
ws_key_x2=0;
ws_key_x1=0;
ws_key_x3=0;
ws_key_y4=0;
ws_key_y2=0;
ws_key_y1=0;
ws_key_y3=0;
ws_key_button_a=0;
ws_key_button_b=0;
if (testJoystick==1)
{
testJoystick=0;
fprintf(log_get(),"%i joysticks were found.\n\n", SDL_NumJoysticks() );
fprintf(log_get(),"The names of the joysticks are:\n");
for(int tti=0; tti < SDL_NumJoysticks(); tti++ )
{
fprintf(log_get()," %s\n", SDL_JoystickName(tti));
}
SDL_JoystickEventState(SDL_ENABLE);
joystick = SDL_JoystickOpen(0);
}
else
{
if (joystick!=NULL)
{
SDL_JoystickClose(0);
SDL_JoystickEventState(SDL_ENABLE);
joystick = SDL_JoystickOpen(0);
}
}
while ( SDL_PollEvent(&app_input_event) )
{
if ( app_input_event.type == SDL_QUIT )
{
ws_key_esc = 1;
}
}
if (joystick)
{
if (SDL_JoystickGetButton(joystick,0))
{
ws_key_start=1;
}
else
{
ws_key_start=0;
}
if (SDL_JoystickGetButton(joystick,1))
{
ws_key_button_a=1;
}
else
{
ws_key_button_a=0;
}
if (SDL_JoystickGetButton(joystick,2))
{
ws_key_button_b=1;
}
else
{
ws_key_button_b=0;
}
if (SDL_JoystickGetAxis(joystick,0)<-7000)
{
ws_key_x4=1;
}
else
{
ws_key_x4=0;
}
if (SDL_JoystickGetAxis(joystick,0)>7000)
{
ws_key_x2=1;
}
else
{
ws_key_x2=0;
}
if (SDL_JoystickGetAxis(joystick,1)<-7000)
{
ws_key_x1=1;
}
else
{
ws_key_x1=0;
}
if (SDL_JoystickGetAxis(joystick,1)>7000)
{
ws_key_x3=1;
}
else
{
ws_key_x3=0;
}
ws_key_y4=0;
ws_key_y2=0;
ws_key_y1=0;
ws_key_y3=0;
}
else
{
ws_key_start=0;
ws_key_x4=0;
ws_key_x2=0;
ws_key_x1=0;
ws_key_x3=0;
ws_key_y4=0;
ws_key_y2=0;
ws_key_y1=0;
ws_key_y3=0;
ws_key_button_a=0;
ws_key_button_b=0;
}
uint8_t *keystate = SDL_GetKeyState(NULL);
if ( keystate[SDLK_e])
if (getKeyState(GLFW_KEY_E))
{
dump_memory();
}
if ( keystate[SDLK_r])
if (getKeyState(GLFW_KEY_R))
{
printf("Boop\n");
ws_reset();
}
if ( keystate[SDLK_ESCAPE] )
if (getKeyState(GLFW_KEY_ESCAPE))
{
ws_key_esc = 1;
}
if ( keystate[SDLK_UP] )
if ( getKeyState(GLFW_KEY_UP))
{
ws_key_x1=1;
}
if ( keystate[SDLK_DOWN] )
if ( getKeyState(GLFW_KEY_DOWN))
{
ws_key_x3=1;
}
if ( keystate[SDLK_RIGHT] )
if (getKeyState(GLFW_KEY_RIGHT))
{
ws_key_x2=1;
}
if ( keystate[SDLK_LEFT] )
if (getKeyState(GLFW_KEY_LEFT))
{
ws_key_x4=1;
}
if (keystate[SDLK_RETURN])
if (getKeyState(GLFW_KEY_ENTER))
{
ws_key_start=1;
}
if (keystate[SDLK_c])
if (getKeyState(GLFW_KEY_C))
{
ws_key_button_a=1;
}
if (keystate[SDLK_x])
if (getKeyState(GLFW_KEY_X))
{
ws_key_button_b=1;
}
if (keystate[SDLK_w])
if (getKeyState(GLFW_KEY_W))
{
ws_key_y1=1;
}
if (keystate[SDLK_a])
if (getKeyState(GLFW_KEY_A))
{
ws_key_y4=1;
}
if (keystate[SDLK_s])
if (getKeyState(GLFW_KEY_S))
{
ws_key_y3=1;
}
if (keystate[SDLK_d])
if (getKeyState(GLFW_KEY_D))
{
ws_key_y2=1;
}
if (keystate[SDLK_o])
if (getKeyState(GLFW_KEY_O))
{
ws_cyclesByLine+=10;
}
if (keystate[SDLK_l])
if (getKeyState(GLFW_KEY_L))
{
ws_cyclesByLine-=10;
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
static void ws_drawDoubledScanline(int16_t *vs, int16_t *backbuffer_alias)
{
register int32_t *vs_alias = (int32_t *)vs;
register int32_t data;
for (int pixel = 0 ; pixel < 224 ; pixel += 8)
{
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
static void ws_drawDoubledRotatedScanline(int16_t *vs, int16_t *backbuffer_alias)
{
register int32_t *vs_alias = (int32_t *)vs;
register int32_t data;
for (int pixel = 0 ; pixel < 144 ; pixel += 8)
{
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_rotate_backbuffer(int16_t *backbuffer)
{
static int16_t temp[224*144];
memcpy(temp,backbuffer,224*144*2);
for (int line=0; line<144; line++)
for (int column=0; column<224; column++)
{
backbuffer[line+((223-column)<<7)+((223-column)<<4)]=temp[column+(line<<7)+(line<<6)+(line<<5)];
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
@@ -379,182 +358,67 @@ void ws_emulate(void)
int i = 0;
double dTime = 0.0, dNormalLast = 0.0, dTemp;
int32_t surfacePitch;
// 15 bits RGB555
Format format(16, 0x007c00, 0x00003e0, 0x0000001f);
Console console;
Surface *surface;
// 15 bits RGB555
//Format format(16, 0x007c00, 0x00003e0, 0x0000001f);
GLWindowInitEx(&mainWindow, 224, 144);
initDisplay(&mainWindow);
clearScreen(&mainWindow);
updateScreen(&mainWindow);
int16_t *backBuffer = (int16_t *)mainWindow.videoMemory;
if (app_rotated)
dNormalLast = (double)getTicks();
while (1)
{
surface = new Surface(144 * 2, 224 * 2, format);
int16_t *backbuffer = (int16_t *)malloc(224 * 144 * sizeof(int16_t));
memset(backbuffer, 0x00, 224 * 144 * sizeof(int16_t));
surfacePitch = (surface->pitch() >> 1);
dNormalLast = (double)SDL_GetTicks();
dTemp = getTicks();
dTime = dTemp - dNormalLast;
console.open(app_window_title, 144 * 2, 224 * 2, format);
while (1)
nCount = (int32_t)(dTime * 0.07547); // does this calculation make sense?
if (nCount <= 0)
{
/* Sleep for 2ms */
usleep(2000);
} // No need to do anything for a bit
else
{
dTemp = (double)SDL_GetTicks();
dTime = dTemp - dNormalLast;
dNormalLast += nCount * (1 / 0.07547);
nCount = (int32_t)(dTime * 0.07547); // does this calculation make sense?
if (nCount <= 0)
if (nCount > 10)
{
SDL_Delay(2);
} // No need to do anything for a bit
else
{
dNormalLast += nCount * (1 / 0.07547);
if (nCount > 10)
{
nCount = 10;
}
read_keys();
if (ws_key_esc)
{
console.close();
app_terminate = 1;
if ((ws_rom_path != NULL) || (app_terminate))
{
break;
}
console.open(app_window_title, 144 * 2, 224 * 2, format);
}
for (i = 0 ; i < nCount - 1 ; i++)
{
while (!ws_executeLine(backbuffer, 0))
{
}
}
while (!ws_executeLine(backbuffer, 1))
{
}
ws_rotate_backbuffer(backbuffer);
int16_t *vs = (int16_t *)surface->lock();
int16_t *backbuffer_alias = backbuffer;
for (int line = 0 ; line < 224 ; line++)
{
ws_drawDoubledRotatedScanline(vs, backbuffer_alias);
vs += surfacePitch;
ws_drawDoubledRotatedScanline(vs, backbuffer_alias);
vs += surfacePitch;
backbuffer_alias += 144;
}
surface->unlock();
surface->copy(console);
console.update();
nCount = 10;
}
}
console.close();
delete surface;
read_keys();
}
else
{
surface = new Surface(224 * 2, 144 * 2, format);
int16_t *backbuffer = (int16_t *)malloc(224 * 144 * sizeof(int16_t));
memset(backbuffer, 0x00, 224 * 144 * sizeof(int16_t));
surfacePitch = (surface->pitch() >> 1);
dNormalLast = (double)SDL_GetTicks();
console.open(app_window_title, 224 * 2, 144 * 2, format);
while (1)
{
dTemp = (double)SDL_GetTicks();
dTime = dTemp - dNormalLast;
nCount = (int32_t)(dTime * 0.07547); // does this calculation make sense?
if (nCount <= 0)
if (ws_key_esc)
{
SDL_Delay(2);
} // No need to do anything for a bit
else
{
dNormalLast += nCount * (1 / 0.07547);
app_terminate = 1;
if (nCount > 10)
if ((ws_rom_path != NULL) || (app_terminate))
{
nCount = 10;
break;
}
read_keys();
if (ws_key_esc)
{
console.close();
app_terminate = 1;
if ((ws_rom_path != NULL) || (app_terminate))
{
break;
}
console.open(app_window_title, 224 * 2, 144 * 2, format);
}
for (i = 0 ; i < nCount - 1 ; i++)
{
while (!ws_executeLine(backbuffer, 0))
{
}
}
while (!ws_executeLine(backbuffer, 1))
{
}
int16_t *vs = (int16_t *)surface->lock();
int16_t *backbuffer_alias = backbuffer;
for (int line = 0 ; line < 144 ; line++)
{
ws_drawDoubledScanline(vs, backbuffer_alias);
vs += surfacePitch;
ws_drawDoubledScanline(vs, backbuffer_alias);
vs += surfacePitch;
backbuffer_alias += 224;
}
surface->unlock();
surface->copy(console);
console.update();
}
}
console.close();
delete surface;
for (i = 0 ; i < nCount - 1 ; i++)
{
while (!ws_executeLine(backBuffer, 0))
{
}
}
while (!ws_executeLine(backBuffer, 1))
{
}
updateScreen(&mainWindow);
}
}
}

View File

@@ -21,7 +21,6 @@ extern char app_window_title[256];
extern int app_gameRunning;
extern int app_terminate;
extern int app_fullscreen;
extern SDL_Event app_input_event;
extern int app_rotated;

View File

@@ -329,6 +329,7 @@ uint8_t cpu_readport(uint8_t port)
int w1,w2;
uint8_t retVal = 0;
/*
if (port > 0x100)
{
port &= 0xFF;
@@ -337,7 +338,7 @@ uint8_t cpu_readport(uint8_t port)
return 0x00;
}
}
*/
switch (port)
{
@@ -1046,6 +1047,7 @@ void cpu_writeport(uint32_t port,uint8_t value)
}
fflush(stdout);
}
break;
case 0xca:
if(value==0x15)

View File

@@ -252,7 +252,7 @@ char *load_file(char *filename)
fstat(fd, &FileStat);
printf("Trying to load %s, size = %lu...\n",filename, FileStat.st_size);
printf("Trying to load %s, size = %lu...\n",filename, (unsigned long)FileStat.st_size);
ret_ptr = (char *)mmap(NULL, FileStat.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
@@ -284,7 +284,7 @@ char *create_file(char *filename, uint32_t size)
char buf[] = { 0 };
printf("Trying to create %s, size = %u...\n",filename, size);
fd = open(filename, O_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | O_TRUNC);
fd = open(filename, O_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | O_TRUNC, 0644);
fchmod(fd, 0644);
close(fd);
sync();

View File

@@ -0,0 +1,4 @@
set(SOURCES nec.cpp)
set(HEADERS nec.h necea.h necinstr.h necintrf.h necmodrm.h)
add_library(nec_v30 ${SOURCES} ${HEADERS})

View File

@@ -3889,7 +3889,7 @@ void nec_set_reg(int regnum, uint32_t val)
}
}
char *instructionsName[256] =
const char *instructionsName[256] =
{
"ADD ", "ADD ", "ADD ", "ADD ", "ADD ", "ADD ", "PUSH", "POP ", "OR ", "OR ", "OR ", "OR ", "OR ", "OR ", "PUSH", "----",
"ADC ", "ADC ", "ADC ", "ADC ", "ADC ", "ADC ", "PUSH", "POP ", "SBB ", "SBB ", "SBB ", "SBB ", "SBB ", "SBB ", "PUSH", "POP ",

View File

@@ -191,6 +191,7 @@ int ws_executeLine(int16_t *framebuffer, int renderLine)
// update scanline register
ws_ioRam[2]=ws_gpu_scanline;
/* Why twice like that and random cycle count???? */
ws_cycles=nec_execute((ws_cyclesByLine>>1)+(rand()&7));
ws_cycles+=nec_execute((ws_cyclesByLine>>1)+(rand()&7));
@@ -459,7 +460,7 @@ int ws_saveState(char *statepath)
}
}
int fp=open(newPath, O_RDWR|O_CREAT);
int fp=open(newPath, O_RDWR|O_CREAT, 0644);
delete newPath;
if (fp==-1)