mirror of https://github.com/stella-emu/stella.git
Retired the GP2X and WinCE ports. This code has been updated in years,
and doesn't currently compile. I don't have the hardware to develop it any further, and no longer have the time in any event. If someone steps up to continue support, it can be added back into the codebase. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2227 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
9cbc1384f4
commit
329f553f09
31
Makefile
31
Makefile
|
@ -69,7 +69,7 @@ endif
|
|||
|
||||
EXECUTABLE := stella$(EXEEXT)
|
||||
|
||||
all: tags $(EXECUTABLE)
|
||||
all: $(EXECUTABLE)
|
||||
|
||||
|
||||
######################################################################
|
||||
|
@ -196,31 +196,4 @@ src/emucore/M6502.ins: src/emucore/M6502.m4
|
|||
src/win32/stella_icon.o: src/win32/stella.ico src/win32/stella.rc
|
||||
$(WINDRES) --include-dir src/win32 src/win32/stella.rc src/win32/stella_icon.o
|
||||
|
||||
# Special target to create a Win32 snapshot package
|
||||
win32dist: stella$(EXEEXT)
|
||||
rm -rf $(DISTNAME)
|
||||
mkdir -p $(DISTNAME)/docs/graphics
|
||||
$(STRIP) stella$(EXEEXT) -o $(DISTNAME)/Stella$(EXEEXT)
|
||||
cp /bin/SDL.dll $(DISTNAME)
|
||||
cp Announce.txt Changes.txt Copyright.txt License.txt README-SDL.txt Readme.txt Todo.txt $(DISTNAME)/docs
|
||||
cp -r docs/*.html $(DISTNAME)/docs
|
||||
cp -r docs/graphics/*.png $(DISTNAME)/docs/graphics
|
||||
# flip -m $(DISTNAME)/docs/*.txt
|
||||
# zip -r $(DISTNAME)-win32.zip $(DISTNAME)
|
||||
|
||||
# GP2X organize: groups necessary files into a gp2x folder for easy access.
|
||||
gp2x-organize:
|
||||
mkdir -p "$(srcdir)/gp2x"
|
||||
mkdir -p "$(srcdir)/gp2x/docs"
|
||||
cp -v $(srcdir)/stella $(srcdir)/gp2x
|
||||
cp -v $(srcdir)/src/gp2x/stella.gpe $(srcdir)/gp2x
|
||||
cp -v $(srcdir)/README-GP2X.txt $(srcdir)/gp2x
|
||||
cp -v -r $(srcdir)/docs/* $(srcdir)/gp2x/docs
|
||||
$(STRIP) $(srcdir)/gp2x/stella
|
||||
|
||||
.PHONY: deb bundle test win32dist install uninstall
|
||||
|
||||
# Use Exuberant ctags (the one from Slackware's vim package, for instance),
|
||||
# not the one from emacs!
|
||||
tags:
|
||||
ctags `find . -name '*.[ch]xx' -o -name '*.c' -o -name '*.y'` || true
|
||||
.PHONY: deb bundle test install uninstall
|
||||
|
|
|
@ -1,237 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
//============================================================================
|
||||
|
||||
#include "FSNode.hxx"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
/*
|
||||
* Implementation of the Stella file system API based on POSIX (for Linux and OSX)
|
||||
*/
|
||||
|
||||
class POSIXFilesystemNode : public AbstractFilesystemNode
|
||||
{
|
||||
public:
|
||||
POSIXFilesystemNode();
|
||||
POSIXFilesystemNode(const string& path);
|
||||
POSIXFilesystemNode(const POSIXFilesystemNode* node);
|
||||
|
||||
virtual string displayName() const { return _displayName; }
|
||||
virtual bool isValid() const { return _isValid; }
|
||||
virtual bool isDirectory() const { return _isDirectory; }
|
||||
virtual string path() const { return _path; }
|
||||
|
||||
virtual FSList listDir(ListMode mode = kListDirectoriesOnly) const;
|
||||
virtual AbstractFilesystemNode* parent() const;
|
||||
|
||||
protected:
|
||||
string _displayName;
|
||||
bool _isDirectory;
|
||||
bool _isValid;
|
||||
string _path;
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
static const char* lastPathComponent(const string& str)
|
||||
{
|
||||
const char *start = str.c_str();
|
||||
const char *cur = start + str.size() - 2;
|
||||
|
||||
while (cur > start && *cur != '/')
|
||||
--cur;
|
||||
|
||||
return cur+1;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
static string validatePath(const string& p)
|
||||
{
|
||||
string path = p;
|
||||
if(p.size() <= 0 || p[0] != '/')
|
||||
path = "/";
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
AbstractFilesystemNode* FilesystemNode::getRoot()
|
||||
{
|
||||
return new POSIXFilesystemNode();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
AbstractFilesystemNode* FilesystemNode::getNodeForPath(const string& path)
|
||||
{
|
||||
return new POSIXFilesystemNode(validatePath(path));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
POSIXFilesystemNode::POSIXFilesystemNode()
|
||||
{
|
||||
char buf[MAXPATHLEN];
|
||||
getcwd(buf, MAXPATHLEN);
|
||||
|
||||
_path = buf;
|
||||
_displayName = lastPathComponent(_path);
|
||||
_path += '/';
|
||||
_isValid = true;
|
||||
_isDirectory = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
POSIXFilesystemNode::POSIXFilesystemNode(const string& p)
|
||||
{
|
||||
string path = validatePath(p);
|
||||
|
||||
Int32 len = 0, offset = path.size();
|
||||
struct stat st;
|
||||
|
||||
_path = path;
|
||||
|
||||
// Extract last component from path
|
||||
const char *str = path.c_str();
|
||||
while (offset > 0 && str[offset-1] == '/')
|
||||
offset--;
|
||||
while (offset > 0 && str[offset-1] != '/')
|
||||
{
|
||||
len++;
|
||||
offset--;
|
||||
}
|
||||
_displayName = string(str + offset, len);
|
||||
|
||||
// Check whether it is a directory, and whether the file actually exists
|
||||
_isValid = (0 == stat(_path.c_str(), &st));
|
||||
_isDirectory = S_ISDIR(st.st_mode);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
POSIXFilesystemNode::POSIXFilesystemNode(const POSIXFilesystemNode* node)
|
||||
{
|
||||
_displayName = node->_displayName;
|
||||
_isValid = node->_isValid;
|
||||
_isDirectory = node->_isDirectory;
|
||||
_path = node->_path;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FSList POSIXFilesystemNode::listDir(ListMode mode) const
|
||||
{
|
||||
DIR *dirp = opendir(_path.c_str());
|
||||
struct stat st;
|
||||
|
||||
struct dirent *dp;
|
||||
FSList myList;
|
||||
|
||||
if (dirp == NULL)
|
||||
return myList;
|
||||
|
||||
// ... loop over dir entries using readdir
|
||||
while ((dp = readdir(dirp)) != NULL)
|
||||
{
|
||||
// Skip 'invisible' files
|
||||
if (dp->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
POSIXFilesystemNode entry;
|
||||
entry._displayName = dp->d_name;
|
||||
entry._path = _path;
|
||||
if (entry._path.length() > 0 && entry._path[entry._path.length()-1] != '/')
|
||||
entry._path += '/';
|
||||
entry._path += dp->d_name;
|
||||
|
||||
if (stat(entry._path.c_str(), &st))
|
||||
continue;
|
||||
entry._isDirectory = S_ISDIR(st.st_mode);
|
||||
|
||||
// Honor the chosen mode
|
||||
if ((mode == kListFilesOnly && entry._isDirectory) ||
|
||||
(mode == kListDirectoriesOnly && !entry._isDirectory))
|
||||
continue;
|
||||
|
||||
if (entry._isDirectory)
|
||||
entry._path += "/";
|
||||
|
||||
myList.push_back(wrap(new POSIXFilesystemNode(&entry)));
|
||||
}
|
||||
closedir(dirp);
|
||||
|
||||
return myList;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
AbstractFilesystemNode *POSIXFilesystemNode::parent() const
|
||||
{
|
||||
if (_path == "/")
|
||||
return 0;
|
||||
|
||||
POSIXFilesystemNode* p = new POSIXFilesystemNode();
|
||||
const char *start = _path.c_str();
|
||||
const char *end = lastPathComponent(_path);
|
||||
|
||||
p->_path = string(start, end - start);
|
||||
p->_displayName = lastPathComponent(p->_path);
|
||||
|
||||
p->_isValid = true;
|
||||
p->_isDirectory = true;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool AbstractFilesystemNode::fileExists(const string& path)
|
||||
{
|
||||
struct stat st;
|
||||
if(stat(path.c_str(), &st) != 0)
|
||||
return false;
|
||||
|
||||
return S_ISREG(st.st_mode);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool AbstractFilesystemNode::dirExists(const string& path)
|
||||
{
|
||||
struct stat st;
|
||||
if(stat(path.c_str(), &st) != 0)
|
||||
return false;
|
||||
|
||||
return S_ISDIR(st.st_mode);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool AbstractFilesystemNode::makeDir(const string& path)
|
||||
{
|
||||
return mkdir(path.c_str(), 0777) == 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool AbstractFilesystemNode::renameFile(const string& oldfile,
|
||||
const string& newfile)
|
||||
{
|
||||
return rename(oldfile.c_str(), newfile.c_str()) == 0;
|
||||
}
|
|
@ -1,417 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "Console.hxx"
|
||||
#include "MediaSrc.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "Font.hxx"
|
||||
#include "Surface.hxx"
|
||||
#include "Settings.hxx"
|
||||
#include "FrameBufferGP2X.hxx"
|
||||
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBufferGP2X::FrameBufferGP2X(OSystem* osystem)
|
||||
: FrameBuffer(osystem),
|
||||
myBasePtr(0),
|
||||
myDirtyFlag(true)
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBufferGP2X::~FrameBufferGP2X()
|
||||
{
|
||||
myTvHeight = 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferGP2X::initSubsystem(VideoMode mode)
|
||||
{
|
||||
// Create the screen
|
||||
return setVidMode(mode);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string FrameBufferGP2X::about() const
|
||||
{
|
||||
// TODO - add SDL info to this string
|
||||
return "";
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferGP2X::setVidMode(VideoMode mode)
|
||||
{
|
||||
const SDL_VideoInfo* info = NULL;
|
||||
|
||||
// Make sure to clear the screen, since we're using different resolutions,
|
||||
// and there tends to be lingering artifacts in hardware mode
|
||||
if(myScreen)
|
||||
{
|
||||
SDL_FillRect(myScreen, NULL, 0);
|
||||
SDL_UpdateRect(myScreen, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
myScreenDim.x = myScreenDim.y = 0;
|
||||
myScreenDim.w = mode.screen_w;
|
||||
myScreenDim.h = mode.screen_h;
|
||||
|
||||
myImageDim.x = mode.image_x;
|
||||
myImageDim.y = mode.image_y;
|
||||
myImageDim.w = mode.image_w;
|
||||
myImageDim.h = mode.image_h;
|
||||
|
||||
// If we got a screenmode that won't be scaled, center it vertically
|
||||
// Otherwise, SDL hardware scaling kicks in, and we won't mess with it
|
||||
if(myBaseDim.h <= 240)
|
||||
{
|
||||
// If we can center vertically, do so
|
||||
// It means the screen we open must be larger than the TIA buffer,
|
||||
// since we're going to start drawing at an y offset
|
||||
myScreenDim.y = (240 - myBaseDim.h) / 2;
|
||||
myScreenDim.h = myScreenDim.y + myBaseDim.h;
|
||||
}
|
||||
|
||||
// check to see if we're displaying on a TV
|
||||
if (!myTvHeight) {
|
||||
info = SDL_GetVideoInfo();
|
||||
|
||||
if (info && info->current_w == 720
|
||||
&& (info->current_h == 480 || info->current_h == 576)) {
|
||||
myTvHeight = info->current_h;
|
||||
|
||||
} else {
|
||||
myTvHeight = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// if I am displaying on a TV then I want to handle overscan
|
||||
// I do this as per the following:
|
||||
// http://www.gp32x.com/board/index.php?showtopic=23819&st=375&p=464689&#entry464689
|
||||
// Basically, I set the screen bigger than the base image. Thus, the image
|
||||
// should be (mostly) on screen. The SDL HW scaler will make sure the
|
||||
// screen fills the TV.
|
||||
if (myTvHeight > 0) {
|
||||
myScreenDim.w = (int)(((float)myScreenDim.w)
|
||||
* myOSystem->settings().getFloat("tv_scale_width"));
|
||||
myScreenDim.h = (int)(((float)myScreenDim.h)
|
||||
* myOSystem->settings().getFloat("tv_scale_height"));
|
||||
|
||||
if ((myScreenDim.w % 2))
|
||||
myScreenDim.w++;
|
||||
|
||||
if ((myScreenDim.h % 2))
|
||||
myScreenDim.h++;
|
||||
|
||||
myScreenDim.x = (myScreenDim.w - mode.screen_w)/2;
|
||||
myScreenDim.y = (myScreenDim.h - mode.screen_h)/2;
|
||||
}
|
||||
|
||||
// The GP2X always uses a 16-bit hardware buffer
|
||||
myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 16, mySDLFlags);
|
||||
if(myScreen == NULL)
|
||||
{
|
||||
cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl;
|
||||
return false;
|
||||
}
|
||||
myPitch = myScreen->pitch/2;
|
||||
myBasePtr = (uInt16*) myScreen->pixels + myScreenDim.y * myPitch;
|
||||
myDirtyFlag = true;
|
||||
myFormat = myScreen->format;
|
||||
|
||||
// Make sure drawMediaSource() knows which renderer to use
|
||||
stateChanged(myOSystem->eventHandler().state());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGP2X::drawMediaSource()
|
||||
{
|
||||
MediaSource& mediasrc = myOSystem->console().mediaSource();
|
||||
|
||||
uInt8* currentFrame = mediasrc.currentFrameBuffer();
|
||||
uInt8* previousFrame = mediasrc.previousFrameBuffer();
|
||||
uInt32 width = mediasrc.width();
|
||||
uInt32 height = mediasrc.height();
|
||||
uInt16* buffer = myBasePtr;
|
||||
|
||||
uInt32 bufofsY = 0;
|
||||
uInt32 screenofsY = 0;
|
||||
|
||||
if(!myUsePhosphor)
|
||||
{
|
||||
for(uInt32 y = 0; y < height; ++y)
|
||||
{
|
||||
uInt32 pos = screenofsY;
|
||||
for(uInt32 x = 0; x < width; ++x)
|
||||
{
|
||||
const uInt32 bufofs = bufofsY + x;
|
||||
uInt8 v = currentFrame[bufofs];
|
||||
uInt8 w = previousFrame[bufofs];
|
||||
|
||||
if(v != w || theRedrawTIAIndicator)
|
||||
{
|
||||
// If we ever get to this point, we know the current and previous
|
||||
// buffers differ. In that case, make sure the changes are
|
||||
// are drawn in postFrameUpdate()
|
||||
myDirtyFlag = true;
|
||||
buffer[pos] = buffer[pos+1] = (uInt16) myDefPalette[v];
|
||||
}
|
||||
pos += 2;
|
||||
}
|
||||
bufofsY += width;
|
||||
screenofsY += myPitch;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Phosphor mode always implies a dirty update,
|
||||
// so we don't care about theRedrawTIAIndicator
|
||||
myDirtyFlag = true;
|
||||
|
||||
for(uInt32 y = 0; y < height; ++y)
|
||||
{
|
||||
uInt32 pos = screenofsY;
|
||||
for(uInt32 x = 0; x < width; ++x)
|
||||
{
|
||||
const uInt32 bufofs = bufofsY + x;
|
||||
uInt8 v = currentFrame[bufofs];
|
||||
uInt8 w = previousFrame[bufofs];
|
||||
|
||||
buffer[pos++] = (uInt16) myAvgPalette[v][w];
|
||||
buffer[pos++] = (uInt16) myAvgPalette[v][w];
|
||||
}
|
||||
bufofsY += width;
|
||||
screenofsY += myPitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGP2X::preFrameUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGP2X::postFrameUpdate()
|
||||
{
|
||||
if(myDirtyFlag)
|
||||
{
|
||||
SDL_Flip(myScreen);
|
||||
myDirtyFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGP2X::scanline(uInt32 row, uInt8* data) const
|
||||
{
|
||||
// Make sure no pixels are being modified
|
||||
SDL_LockSurface(myScreen);
|
||||
|
||||
uInt32 bpp = myScreen->format->BytesPerPixel;
|
||||
uInt8* start = (uInt8*) myBasePtr;
|
||||
uInt32 yoffset = row * myScreen->pitch;
|
||||
uInt32 pixel = 0;
|
||||
uInt8 *p, r, g, b;
|
||||
|
||||
for(Int32 x = 0; x < myBaseDim.w; ++x)
|
||||
{
|
||||
p = (Uint8*) (start + // Start at top of RAM
|
||||
(yoffset) + // Go down 'row' lines
|
||||
(x * bpp)); // Go in 'x' pixels
|
||||
|
||||
pixel = *(Uint16*) p;
|
||||
SDL_GetRGB(pixel, myScreen->format, &r, &g, &b);
|
||||
|
||||
data[x * 3 + 0] = r;
|
||||
data[x * 3 + 1] = g;
|
||||
data[x * 3 + 2] = b;
|
||||
}
|
||||
|
||||
SDL_UnlockSurface(myScreen);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGP2X::toggleFilter()
|
||||
{
|
||||
// Not supported
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGP2X::hLine(uInt32 x, uInt32 y, uInt32 x2, int color)
|
||||
{
|
||||
SDL_Rect tmp;
|
||||
|
||||
// Horizontal line
|
||||
tmp.x = x;
|
||||
tmp.y = y + myScreenDim.y;
|
||||
tmp.w = (x2 - x + 1);
|
||||
tmp.h = 1;
|
||||
SDL_FillRect(myScreen, &tmp, myDefPalette[color]);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGP2X::vLine(uInt32 x, uInt32 y, uInt32 y2, int color)
|
||||
{
|
||||
SDL_Rect tmp;
|
||||
|
||||
// Vertical line
|
||||
tmp.x = x;
|
||||
tmp.y = y + myScreenDim.y;
|
||||
tmp.w = 1;
|
||||
tmp.h = (y2 - y + 1);
|
||||
SDL_FillRect(myScreen, &tmp, myDefPalette[color]);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGP2X::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
||||
int color)
|
||||
{
|
||||
SDL_Rect tmp;
|
||||
|
||||
// Fill the rectangle
|
||||
tmp.x = x;
|
||||
tmp.y = y + myScreenDim.y;
|
||||
tmp.w = w;
|
||||
tmp.h = h;
|
||||
SDL_FillRect(myScreen, &tmp, myDefPalette[color]);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGP2X::drawChar(const GUI::Font* font, uInt8 chr,
|
||||
uInt32 xorig, uInt32 yorig, int color)
|
||||
{
|
||||
const FontDesc& desc = font->desc();
|
||||
|
||||
// If this character is not included in the font, use the default char.
|
||||
if(chr < desc.firstchar || chr >= desc.firstchar + desc.size)
|
||||
{
|
||||
if (chr == ' ')
|
||||
return;
|
||||
chr = desc.defaultchar;
|
||||
}
|
||||
|
||||
const Int32 w = font->getCharWidth(chr);
|
||||
const Int32 h = font->getFontHeight();
|
||||
chr -= desc.firstchar;
|
||||
const uInt16* tmp = desc.bits + (desc.offset ? desc.offset[chr] : (chr * h));
|
||||
|
||||
uInt16* buffer = (uInt16*) myBasePtr + yorig * myPitch + xorig;
|
||||
for(int y = 0; y < h; ++y)
|
||||
{
|
||||
const uInt16 ptr = *tmp++;
|
||||
uInt16 mask = 0x8000;
|
||||
for(int x = 0; x < w; ++x, mask >>= 1)
|
||||
if(ptr & mask)
|
||||
buffer[x] = (uInt16) myDefPalette[color];
|
||||
|
||||
buffer += myPitch;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGP2X::drawBitmap(uInt32* bitmap, Int32 xorig, Int32 yorig,
|
||||
int color, Int32 h)
|
||||
{
|
||||
uInt16* buffer = (uInt16*) myBasePtr + yorig * myPitch + xorig;
|
||||
for(int y = 0; y < h; ++y)
|
||||
{
|
||||
uInt32 mask = 0xF0000000;
|
||||
for(int x = 0; x < 8; ++x, mask >>= 4)
|
||||
if(bitmap[y] & mask)
|
||||
buffer[x] = (uInt16) myDefPalette[color];
|
||||
|
||||
buffer += myPitch;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGP2X::drawSurface(const GUI::Surface* surface, Int32 x, Int32 y)
|
||||
{
|
||||
/* TODO - not supported yet
|
||||
SDL_Rect clip;
|
||||
clip.x = x;
|
||||
clip.y = y;
|
||||
|
||||
SDL_BlitSurface(surface->myData, 0, myScreen, &clip);
|
||||
*/
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGP2X::bytesToSurface(GUI::Surface* surface, int row,
|
||||
uInt8* data, int rowbytes) const
|
||||
{
|
||||
/* TODO - not supported yet
|
||||
SDL_Surface* s = surface->myData;
|
||||
|
||||
uInt16* pixels = (uInt16*) s->pixels;
|
||||
int surfbytes = s->pitch/2;
|
||||
pixels += (row * surfbytes);
|
||||
|
||||
// Calculate a scanline of zoomed surface data
|
||||
for(int c = 0; c < rowbytes; c += 3)
|
||||
{
|
||||
uInt32 pixel = SDL_MapRGB(s->format, data[c], data[c+1], data[c+2]);
|
||||
*pixels++ = pixel;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
GUI::Surface* FrameBufferGP2X::createSurface(int width, int height) const
|
||||
{
|
||||
SDL_Surface* data =
|
||||
SDL_CreateRGBSurface(SDL_SWSURFACE, width, height,
|
||||
16, myFormat->Rmask, myFormat->Gmask,
|
||||
myFormat->Bmask, myFormat->Amask);
|
||||
|
||||
return data ? new GUI::Surface(width, height, data) : NULL;
|
||||
}
|
||||
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGP2X::translateCoords(Int32& x, Int32& y) const
|
||||
{
|
||||
// Coordinates don't change
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGP2X::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
|
||||
{
|
||||
// We're using a hardware buffer; just indicate that the buffer is dirty
|
||||
myDirtyFlag = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGP2X::enablePhosphor(bool enable, int blend)
|
||||
{
|
||||
myUsePhosphor = enable;
|
||||
myPhosphorBlend = blend;
|
||||
|
||||
theRedrawTIAIndicator = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGP2X::showCursor(bool show)
|
||||
{
|
||||
// Never show the cursor
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
}
|
|
@ -1,251 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#ifndef FRAMEBUFFER_GP2X_HXX
|
||||
#define FRAMEBUFFER_GP2X_HXX
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
class OSystem;
|
||||
class GUI::Font;
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
|
||||
|
||||
/**
|
||||
This class implements an SDL hardware framebuffer for the GP2X device.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id$
|
||||
*/
|
||||
class FrameBufferGP2X : public FrameBuffer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Creates a new software framebuffer
|
||||
*/
|
||||
FrameBufferGP2X(OSystem* osystem);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
*/
|
||||
virtual ~FrameBufferGP2X();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// The following methods are derived from FrameBuffer.hxx
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
This method is called to initialize software video mode.
|
||||
Return false if any operation fails, otherwise return true.
|
||||
*/
|
||||
virtual bool initSubsystem(VideoMode mode);
|
||||
|
||||
/**
|
||||
This method is called to query the type of the FrameBuffer.
|
||||
*/
|
||||
virtual BufferType type() const { return kSoftBuffer; }
|
||||
|
||||
/**
|
||||
This method is called to provide information about the FrameBuffer.
|
||||
*/
|
||||
virtual string about() const;
|
||||
|
||||
/**
|
||||
This method is called to change to the given videomode type.
|
||||
|
||||
@param mode The video mode to use for rendering the mediasource
|
||||
*/
|
||||
bool setVidMode(VideoMode mode);
|
||||
|
||||
/**
|
||||
Switches between the filtering options in software mode.
|
||||
Currently, none exist.
|
||||
*/
|
||||
virtual void toggleFilter();
|
||||
|
||||
/**
|
||||
This method should be called anytime the MediaSource needs to be redrawn
|
||||
to the screen.
|
||||
*/
|
||||
virtual void drawMediaSource();
|
||||
|
||||
/**
|
||||
This method is called before any drawing is done (per-frame).
|
||||
*/
|
||||
virtual void preFrameUpdate();
|
||||
|
||||
/**
|
||||
This method is called after any drawing is done (per-frame).
|
||||
*/
|
||||
virtual void postFrameUpdate();
|
||||
|
||||
/**
|
||||
This method is called to get the specified scanline data.
|
||||
|
||||
@param row The row we are looking for
|
||||
@param data The actual pixel data (in bytes)
|
||||
*/
|
||||
virtual void scanline(uInt32 row, uInt8* data) const;
|
||||
|
||||
/**
|
||||
This method is called to map a given r,g,b triple to the screen palette.
|
||||
|
||||
@param r The red component of the color.
|
||||
@param g The green component of the color.
|
||||
@param b The blue component of the color.
|
||||
*/
|
||||
virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b) const
|
||||
{ return SDL_MapRGB(myScreen->format, r, g, b); }
|
||||
|
||||
/**
|
||||
This method is called to create a surface compatible with the one
|
||||
currently in use, but having the given dimensions.
|
||||
|
||||
@param width The requested width of the new surface.
|
||||
@param height The requested height of the new surface.
|
||||
*/
|
||||
GUI::Surface* createSurface(int width, int height) const;
|
||||
|
||||
/**
|
||||
This method is called to draw a horizontal line.
|
||||
|
||||
@param x The first x coordinate
|
||||
@param y The y coordinate
|
||||
@param x2 The second x coordinate
|
||||
@param color The color of the line
|
||||
*/
|
||||
virtual void hLine(uInt32 x, uInt32 y, uInt32 x2, int color);
|
||||
|
||||
/**
|
||||
This method is called to draw a vertical line.
|
||||
|
||||
@param x The x coordinate
|
||||
@param y The first y coordinate
|
||||
@param y2 The second y coordinate
|
||||
@param color The color of the line
|
||||
*/
|
||||
virtual void vLine(uInt32 x, uInt32 y, uInt32 y2, int color);
|
||||
|
||||
/**
|
||||
This method is called to draw a filled rectangle.
|
||||
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param w The width of the area
|
||||
@param h The height of the area
|
||||
@param color The color of the area
|
||||
*/
|
||||
virtual void fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
||||
int color);
|
||||
|
||||
/**
|
||||
This method is called to draw the specified character.
|
||||
|
||||
@param font The font to use to draw the character
|
||||
@param c The character to draw
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param color The color of the character
|
||||
*/
|
||||
virtual void drawChar(const GUI::Font* font, uInt8 c, uInt32 x, uInt32 y,
|
||||
int color);
|
||||
|
||||
/**
|
||||
This method is called to draw the bitmap image.
|
||||
|
||||
@param bitmap The data to draw
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param color The color of the character
|
||||
@param h The height of the data image
|
||||
*/
|
||||
virtual void drawBitmap(uInt32* bitmap, Int32 x, Int32 y, int color,
|
||||
Int32 h = 8);
|
||||
|
||||
/**
|
||||
This method should be called to draw an SDL surface.
|
||||
|
||||
@param surface The data to draw
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
*/
|
||||
void drawSurface(const GUI::Surface* surface, Int32 x, Int32 y);
|
||||
|
||||
/**
|
||||
This method should be called to convert and copy a given row of RGB
|
||||
data into an SDL surface.
|
||||
|
||||
@param surface The data to draw
|
||||
@param row The row of the surface the data should be placed in
|
||||
@param data The data in uInt8 R/G/B format
|
||||
@param rowbytes The number of bytes in row of 'data'
|
||||
*/
|
||||
void bytesToSurface(GUI::Surface* surface, int row,
|
||||
uInt8* data, int rowbytes) const;
|
||||
|
||||
/**
|
||||
This method translates the given coordinates to their
|
||||
unzoomed/unscaled equivalents.
|
||||
|
||||
@param x X coordinate to translate
|
||||
@param y Y coordinate to translate
|
||||
*/
|
||||
virtual void translateCoords(Int32& x, Int32& y) const;
|
||||
|
||||
/**
|
||||
This method adds a dirty rectangle
|
||||
(ie, an area of the screen that has changed)
|
||||
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param w The width of the area
|
||||
@param h The height of the area
|
||||
*/
|
||||
virtual void addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h);
|
||||
|
||||
/**
|
||||
Enable/disable phosphor effect.
|
||||
*/
|
||||
virtual void enablePhosphor(bool enable, int blend);
|
||||
|
||||
/**
|
||||
Shows or hides the cursor based on the given boolean value.
|
||||
*/
|
||||
virtual void showCursor(bool show);
|
||||
|
||||
private:
|
||||
// Origin at which to access the FrameBuffer
|
||||
// This point is treated as (0, 0) wrt the TIA image
|
||||
uInt16* myBasePtr;
|
||||
|
||||
// Indicates that the buffer is dirty, and should be redrawn/flipped
|
||||
bool myDirtyFlag;
|
||||
|
||||
// Pitch (in bytes) of the current screen
|
||||
int myPitch;
|
||||
|
||||
// surface pixel format
|
||||
SDL_PixelFormat* myFormat;
|
||||
|
||||
// the height of the display for TV output
|
||||
int myTvHeight;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,218 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id$
|
||||
// Modified on 2006/01/06 by Alex Zaballa for use on GP2X
|
||||
//============================================================================
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "OSystemGP2X.hxx"
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
Each derived class is responsible for calling the following methods
|
||||
in its constructor:
|
||||
|
||||
setBaseDir()
|
||||
setStateDir()
|
||||
setPropertiesDir()
|
||||
setConfigFile()
|
||||
setCacheFile()
|
||||
|
||||
See OSystem.hxx for a further explanation
|
||||
*/
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
OSystemGP2X::OSystemGP2X() : OSystem()
|
||||
{
|
||||
// GP2X needs all config files in exec directory
|
||||
|
||||
char *currdir = getcwd(NULL, 0);
|
||||
string basedir = currdir;
|
||||
free(currdir);
|
||||
setBaseDir(basedir);
|
||||
|
||||
setConfigFile(basedir + "/stellarc");
|
||||
|
||||
setCacheFile(basedir + "/stella.cache");
|
||||
|
||||
// Set event arrays to a known state
|
||||
myPreviousEvents = new uInt8[8]; memset(myPreviousEvents, 0, 8);
|
||||
myCurrentEvents = new uInt8[8]; memset(myCurrentEvents, 0, 8);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
OSystemGP2X::~OSystemGP2X()
|
||||
{
|
||||
delete[] myPreviousEvents;
|
||||
delete[] myCurrentEvents;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 OSystemGP2X::getTicks() const
|
||||
{
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
timeval now;
|
||||
gettimeofday(&now, 0);
|
||||
|
||||
return (uInt32) (now.tv_sec * 1000000 + now.tv_usec);
|
||||
#else
|
||||
return (uInt32) SDL_GetTicks() * 1000;
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void OSystemGP2X::getScreenDimensions(int& width, int& height)
|
||||
{
|
||||
width = 400;
|
||||
height = 300;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void OSystemGP2X::setDefaultJoymap()
|
||||
{
|
||||
myEventHandler->setDefaultJoyMapping(Event::LauncherMode, kEmulationMode, 0, 8); // Start
|
||||
myEventHandler->setDefaultJoyMapping(Event::TakeSnapshot, kEmulationMode, 0, 9); // Select
|
||||
myEventHandler->setDefaultJoyMapping(Event::ConsoleReset, kEmulationMode, 0, 10); // L
|
||||
myEventHandler->setDefaultJoyMapping(Event::ConsoleSelect, kEmulationMode, 0, 11); // R
|
||||
myEventHandler->setDefaultJoyMapping(Event::CmdMenuMode, kEmulationMode, 0, 12); // A
|
||||
myEventHandler->setDefaultJoyMapping(Event::JoystickZeroFire1, kEmulationMode, 0, 13); // B
|
||||
myEventHandler->setDefaultJoyMapping(Event::MenuMode, kEmulationMode, 0, 14); // Y
|
||||
// myEventHandler->setDefaultJoyMapping(Event::Pause, kEmulationMode, 0, 15); // X
|
||||
myEventHandler->setDefaultJoyMapping(Event::VolumeIncrease, kEmulationMode, 0, 16); // Vol+
|
||||
myEventHandler->setDefaultJoyMapping(Event::VolumeDecrease, kEmulationMode, 0, 17); // Vol-
|
||||
myEventHandler->setDefaultJoyMapping(Event::NoType, kEmulationMode, 0, 18); // Click
|
||||
//Begin Menu Navigation Mapping
|
||||
myEventHandler->setDefaultJoyMapping(Event::UICancel, kMenuMode, 0, 8); // Start
|
||||
myEventHandler->setDefaultJoyMapping(Event::UIOK, kMenuMode, 0, 9); // Select
|
||||
myEventHandler->setDefaultJoyMapping(Event::UIPgUp, kMenuMode, 0, 10); // L
|
||||
myEventHandler->setDefaultJoyMapping(Event::UIPgDown, kMenuMode, 0, 11); // R
|
||||
// myEventHandler->setDefaultJoyMapping(Event::UITabPrev, kMenuMode, 0, 12); // A
|
||||
myEventHandler->setDefaultJoyMapping(Event::UISelect, kMenuMode, 0, 13); // B
|
||||
// myEventHandler->setDefaultJoyMapping(Event::UITabNext, kMenuMode, 0, 14); // Y
|
||||
myEventHandler->setDefaultJoyMapping(Event::UICancel, kMenuMode, 0, 15); // X
|
||||
myEventHandler->setDefaultJoyMapping(Event::UINavNext, kMenuMode, 0, 16); // Vol+
|
||||
myEventHandler->setDefaultJoyMapping(Event::UINavPrev, kMenuMode, 0, 17); // Vol-
|
||||
myEventHandler->setDefaultJoyMapping(Event::NoType, kMenuMode, 0, 18); // Click
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void OSystemGP2X::pollEvent()
|
||||
{
|
||||
// Translate joystick button events that act as directions into proper
|
||||
// SDL axis events. This method will use 'case 2', as discussed on the
|
||||
// GP2X forums. Technically, this code should be integrated directly
|
||||
// into the GP2X SDL port.
|
||||
|
||||
// Swap event buffers
|
||||
uInt8* tmp = myCurrentEvents;
|
||||
myCurrentEvents = myPreviousEvents;
|
||||
myPreviousEvents = tmp;
|
||||
|
||||
// Scan all the buttons, and detect if an event has occurred
|
||||
bool changeDetected = false;
|
||||
SDL_Joystick* stick = myEventHandler->getJoystick(0);
|
||||
for(int i = 0; i < 8; ++i)
|
||||
{
|
||||
myCurrentEvents[i] = SDL_JoystickGetButton(stick, i);
|
||||
myActiveEvents[i] = myCurrentEvents[i] != myPreviousEvents[i];
|
||||
changeDetected = changeDetected || myActiveEvents[i];
|
||||
}
|
||||
|
||||
if(changeDetected)
|
||||
{
|
||||
SDL_JoyAxisEvent eventA0, eventA1;
|
||||
eventA0.type = eventA1.type = SDL_JOYAXISMOTION;
|
||||
eventA0.which = eventA1.which = 0;
|
||||
eventA0.value = 0;eventA1.value = 0;
|
||||
eventA0.axis = 0;
|
||||
eventA1.axis = 1;
|
||||
|
||||
bool axisZeroChanged = false, axisOneChanged = false;
|
||||
|
||||
axisOneChanged = axisOneChanged || myActiveEvents[kJDirUp];
|
||||
if(myCurrentEvents[kJDirUp]) // up
|
||||
{
|
||||
eventA1.value = -32768;
|
||||
}
|
||||
axisOneChanged = axisOneChanged || myActiveEvents[kJDirDown];
|
||||
if(myCurrentEvents[kJDirDown]) // down
|
||||
{
|
||||
eventA1.value = 32767;
|
||||
}
|
||||
axisZeroChanged = axisZeroChanged || myActiveEvents[kJDirLeft];
|
||||
if(myCurrentEvents[kJDirLeft]) // left
|
||||
{
|
||||
eventA0.value = -32768;
|
||||
}
|
||||
axisZeroChanged = axisZeroChanged || myActiveEvents[kJDirRight];
|
||||
if(myCurrentEvents[kJDirRight]) // right
|
||||
{
|
||||
eventA0.value = 32767;
|
||||
}
|
||||
|
||||
axisOneChanged = axisOneChanged || myActiveEvents[kJDirUpLeft];
|
||||
axisZeroChanged = axisZeroChanged || myActiveEvents[kJDirUpLeft];
|
||||
if(myCurrentEvents[kJDirUpLeft]) // up-left
|
||||
{
|
||||
eventA1.value = -16834;
|
||||
eventA0.value = -16834;
|
||||
}
|
||||
axisOneChanged = axisOneChanged || myActiveEvents[kJDirUpRight];
|
||||
axisZeroChanged = axisZeroChanged || myActiveEvents[kJDirUpRight];
|
||||
if(myCurrentEvents[kJDirUpRight]) // up-right
|
||||
{
|
||||
eventA1.value = -16834;
|
||||
eventA0.value = 16834;
|
||||
}
|
||||
axisOneChanged = axisOneChanged || myActiveEvents[kJDirDownLeft];
|
||||
axisZeroChanged = axisZeroChanged || myActiveEvents[kJDirDownLeft];
|
||||
if(myCurrentEvents[kJDirDownLeft]) // down-left
|
||||
{
|
||||
eventA1.value = 16834;
|
||||
eventA0.value = -16834;
|
||||
}
|
||||
axisOneChanged = axisOneChanged || myActiveEvents[kJDirDownRight];
|
||||
axisZeroChanged = axisZeroChanged || myActiveEvents[kJDirDownRight];
|
||||
if(myCurrentEvents[kJDirDownRight]) // down-right
|
||||
{
|
||||
eventA1.value = 16834;
|
||||
eventA0.value = 16834;
|
||||
}
|
||||
|
||||
if(axisZeroChanged) SDL_PushEvent((SDL_Event*)&eventA0);
|
||||
if(axisOneChanged) SDL_PushEvent((SDL_Event*)&eventA1);
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool OSystemGP2X::joyButtonHandled(int button)
|
||||
{
|
||||
return (button < 8);
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id$
|
||||
// Modified by Alex Zaballa on 2006/01/04 for use on GP2X
|
||||
//============================================================================
|
||||
|
||||
#ifndef OSYSTEM_GP2X_HXX
|
||||
#define OSYSTEM_GP2X_HXX
|
||||
|
||||
#include "bspf.hxx"
|
||||
|
||||
|
||||
/**
|
||||
This class defines GP2X system specific settings.
|
||||
*/
|
||||
class OSystemGP2X : public OSystem
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Create a new GP2X-specific operating system object
|
||||
*/
|
||||
OSystemGP2X();
|
||||
|
||||
/**
|
||||
Destructor
|
||||
*/
|
||||
virtual ~OSystemGP2X();
|
||||
|
||||
public:
|
||||
/**
|
||||
This method returns number of ticks in microseconds.
|
||||
|
||||
@return Current time in microseconds.
|
||||
*/
|
||||
uInt32 getTicks() const;
|
||||
|
||||
/**
|
||||
This method queries the dimensions of the screen for this hardware.
|
||||
*/
|
||||
void getScreenDimensions(int& width, int& height);
|
||||
|
||||
/**
|
||||
This method determines the default mapping of joystick buttons to
|
||||
Stella events for the PSP device.
|
||||
*/
|
||||
void setDefaultJoymap();
|
||||
|
||||
/**
|
||||
This method creates events from platform-specific hardware.
|
||||
*/
|
||||
void pollEvent();
|
||||
|
||||
/**
|
||||
This method answers whether the given button as already been
|
||||
handled by the pollEvent() method, and as such should be ignored
|
||||
in the main event handler.
|
||||
*/
|
||||
bool joyButtonHandled(int button);
|
||||
|
||||
private:
|
||||
enum {
|
||||
kJDirUp = 0, kJDirUpLeft = 1,
|
||||
kJDirLeft = 2, kJDirDownLeft = 3,
|
||||
kJDirDown = 4, kJDirDownRight = 5,
|
||||
kJDirRight = 6, kJDirUpRight = 7
|
||||
};
|
||||
|
||||
uInt8* myPreviousEvents;
|
||||
uInt8* myCurrentEvents;
|
||||
bool myActiveEvents[8];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,55 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id$
|
||||
// Modified on 2006/02/05 by Alex Zaballa for use on GP2X
|
||||
//============================================================================
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "Settings.hxx"
|
||||
#include "SettingsGP2X.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
SettingsGP2X::SettingsGP2X(OSystem* osystem)
|
||||
: Settings(osystem)
|
||||
{
|
||||
// Some of these settings might be redundant, but are crucial for GP2X
|
||||
setInternal("center", "true");
|
||||
setInternal("volume", "33");
|
||||
setInternal("sound", "true");
|
||||
setInternal("zoom", "1");
|
||||
setInternal("fragsize", "256");
|
||||
setInternal("freq", "15700");
|
||||
setInternal("tiafreq", "15700");
|
||||
setInternal("clipvol", "false");
|
||||
setInternal("rombrowse", "true");
|
||||
setInternal("romdir", "/mnt/sd/");
|
||||
setInternal("ssdir", "/mnt/sd/");
|
||||
setInternal("p0speed", "15");
|
||||
setInternal("p1speed", "15");
|
||||
setInternal("p2speed", "15");
|
||||
setInternal("p3speed", "15");
|
||||
setInternal("launchersize", "1");
|
||||
setInternal("uipalette", "2");
|
||||
setInternal("tv_scale_width", "1.125");
|
||||
setInternal("tv_scale_height", "1.2");
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
SettingsGP2X::~SettingsGP2X()
|
||||
{
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id$
|
||||
// Modified by Alex Zaballa on 2006/01/04 for use on GP2X
|
||||
//============================================================================
|
||||
|
||||
#ifndef SETTINGS_GP2X_HXX
|
||||
#define SETTINGS_GP2X_HXX
|
||||
|
||||
class OSystem;
|
||||
|
||||
#include "bspf.hxx"
|
||||
|
||||
/**
|
||||
This class defines GP2X system specific settings.
|
||||
*/
|
||||
class SettingsGP2X : public Settings
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Create a new GP2X settings object
|
||||
*/
|
||||
SettingsGP2X(OSystem* osystem);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
*/
|
||||
virtual ~SettingsGP2X();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,12 +0,0 @@
|
|||
MODULE := src/gp2x
|
||||
|
||||
MODULE_OBJS := \
|
||||
src/gp2x/FrameBufferGP2X.o \
|
||||
src/gp2x/FSNodeGP2X.o \
|
||||
src/gp2x/OSystemGP2X.o \
|
||||
src/gp2x/SettingsGP2X.o
|
||||
MODULE_DIRS += \
|
||||
src/gp2x
|
||||
|
||||
# Include common rules
|
||||
include $(srcdir)/common.rules
|
|
@ -1,15 +0,0 @@
|
|||
#!/bin/sh
|
||||
#########################################################################
|
||||
# Stella Exit Wrapper for GP2X
|
||||
# Questions, comments, or suggestions:
|
||||
# Email me at azaballa@users.sourceforge.net
|
||||
# Thanx to remowilliams, once again, for the help
|
||||
# and for this script.
|
||||
# Do not edit this file... that is unless you know what you are doing. ;)
|
||||
#########################################################################
|
||||
|
||||
./stella
|
||||
sync
|
||||
|
||||
cd /usr/gp2x/
|
||||
exec /usr/gp2x/gp2xmenu
|
|
@ -1,280 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// Windows CE Port by Kostas Nakos
|
||||
//============================================================================
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#include "FSNode.hxx"
|
||||
|
||||
/*
|
||||
* Implementation of the Stella file system API based on Windows CE API.
|
||||
* Modified from the Win32 version
|
||||
*/
|
||||
|
||||
class WindowsFilesystemNode : public AbstractFilesystemNode
|
||||
{
|
||||
public:
|
||||
WindowsFilesystemNode();
|
||||
WindowsFilesystemNode(const string &path);
|
||||
WindowsFilesystemNode(const WindowsFilesystemNode* node);
|
||||
|
||||
virtual string displayName() const { return _displayName; }
|
||||
virtual bool isValid() const { return _isValid; }
|
||||
virtual bool isDirectory() const { return _isDirectory; }
|
||||
virtual string path() const { return _path; }
|
||||
|
||||
virtual FSList listDir(ListMode) const;
|
||||
virtual AbstractFilesystemNode* parent() const;
|
||||
|
||||
protected:
|
||||
string _displayName;
|
||||
bool _isDirectory;
|
||||
bool _isValid;
|
||||
bool _isPseudoRoot;
|
||||
string _path;
|
||||
|
||||
private:
|
||||
static char* toAscii(TCHAR* x);
|
||||
static TCHAR* toUnicode(char* x);
|
||||
static void addFile (FSList& list, ListMode mode,
|
||||
const char* base, WIN32_FIND_DATA* find_data);
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
static const char* lastPathComponent(const string& str)
|
||||
{
|
||||
const char* start = str.c_str();
|
||||
const char* cur = start + str.size() - 2;
|
||||
|
||||
while (cur > start && *cur != '\\')
|
||||
--cur;
|
||||
|
||||
return cur + 1;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
static string validatePath(const string& p)
|
||||
{
|
||||
string path = p;
|
||||
|
||||
if (p.size() < 2) path = "\\";
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
char* WindowsFilesystemNode::toAscii(TCHAR* x)
|
||||
{
|
||||
#ifndef UNICODE
|
||||
return (char*)x;
|
||||
#else
|
||||
static char asciiString[MAX_PATH];
|
||||
WideCharToMultiByte(CP_ACP, 0, x, _tcslen(x) + 1, asciiString, sizeof(asciiString), NULL, NULL);
|
||||
return asciiString;
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
TCHAR* WindowsFilesystemNode::toUnicode(char* x)
|
||||
{
|
||||
#ifndef UNICODE
|
||||
return (TCHAR*)x;
|
||||
#else
|
||||
static TCHAR unicodeString[MAX_PATH];
|
||||
MultiByteToWideChar(CP_ACP, 0, x, strlen(x) + 1, unicodeString, sizeof(unicodeString));
|
||||
return unicodeString;
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void WindowsFilesystemNode::addFile(FSList& list, ListMode mode,
|
||||
const char* base, WIN32_FIND_DATA* find_data)
|
||||
{
|
||||
WindowsFilesystemNode entry;
|
||||
char* asciiName = toAscii(find_data->cFileName);
|
||||
bool isDirectory;
|
||||
|
||||
// Skip local directory (.) and parent (..)
|
||||
if (!strcmp(asciiName, ".") || !strcmp(asciiName, ".."))
|
||||
return;
|
||||
|
||||
isDirectory = (find_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? true : false);
|
||||
|
||||
if ((!isDirectory && mode == kListDirectoriesOnly) ||
|
||||
(isDirectory && mode == kListFilesOnly))
|
||||
return;
|
||||
|
||||
entry._isDirectory = isDirectory;
|
||||
entry._displayName = asciiName;
|
||||
entry._path = base;
|
||||
entry._path += asciiName;
|
||||
if (entry._isDirectory)
|
||||
entry._path += "\\";
|
||||
entry._isValid = true;
|
||||
entry._isPseudoRoot = false;
|
||||
|
||||
list.push_back(wrap(new WindowsFilesystemNode(&entry)));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
AbstractFilesystemNode* FilesystemNode::getRoot()
|
||||
{
|
||||
return new WindowsFilesystemNode();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
AbstractFilesystemNode* FilesystemNode::getNodeForPath(const string& path)
|
||||
{
|
||||
return new WindowsFilesystemNode(path);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
WindowsFilesystemNode::WindowsFilesystemNode()
|
||||
{
|
||||
_isDirectory = true;
|
||||
|
||||
// Create a virtual root directory for standard Windows system
|
||||
_isValid = false;
|
||||
_path = "\\";
|
||||
_isPseudoRoot = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
WindowsFilesystemNode::WindowsFilesystemNode(const string& path)
|
||||
{
|
||||
_path = validatePath(path);
|
||||
_displayName = lastPathComponent(_path);
|
||||
_isValid = true;
|
||||
_isDirectory = true;
|
||||
_isPseudoRoot = false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
WindowsFilesystemNode::WindowsFilesystemNode(const WindowsFilesystemNode* node)
|
||||
{
|
||||
_displayName = node->_displayName;
|
||||
_isDirectory = node->_isDirectory;
|
||||
_isValid = node->_isValid;
|
||||
_isPseudoRoot = node->_isPseudoRoot;
|
||||
_path = node->_path;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FSList WindowsFilesystemNode::listDir(ListMode mode) const
|
||||
{
|
||||
assert(_isDirectory);
|
||||
|
||||
FSList myList;
|
||||
|
||||
// Files enumeration
|
||||
WIN32_FIND_DATA desc;
|
||||
HANDLE handle;
|
||||
char searchPath[MAX_PATH + 10];
|
||||
|
||||
sprintf(searchPath, "%s*", _path.c_str());
|
||||
|
||||
handle = FindFirstFile(toUnicode(searchPath), &desc);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return myList;
|
||||
|
||||
addFile(myList, mode, _path.c_str(), &desc);
|
||||
while (FindNextFile(handle, &desc))
|
||||
addFile(myList, mode, _path.c_str(), &desc);
|
||||
|
||||
FindClose(handle);
|
||||
|
||||
return myList;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
AbstractFilesystemNode* WindowsFilesystemNode::parent() const
|
||||
{
|
||||
assert(_isValid || _isPseudoRoot);
|
||||
if (_isPseudoRoot)
|
||||
return 0;
|
||||
|
||||
WindowsFilesystemNode* p = new WindowsFilesystemNode();
|
||||
if (_path.size() > 3)
|
||||
{
|
||||
const char *start = _path.c_str();
|
||||
const char *end = lastPathComponent(_path);
|
||||
|
||||
p = new WindowsFilesystemNode();
|
||||
p->_path = string(start, end - start);
|
||||
p->_isValid = true;
|
||||
p->_isDirectory = true;
|
||||
p->_displayName = lastPathComponent(p->_path);
|
||||
p->_isPseudoRoot = false;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool AbstractFilesystemNode::fileExists(const string& path)
|
||||
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA attr;
|
||||
|
||||
static TCHAR unicodeString[MAX_PATH];
|
||||
MultiByteToWideChar(CP_ACP, 0, path.c_str(), strlen(path.c_str()) + 1, unicodeString, sizeof(unicodeString));
|
||||
|
||||
BOOL b = GetFileAttributesEx(unicodeString, GetFileExInfoStandard, &attr);
|
||||
|
||||
return ((b != 0) && !(attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool AbstractFilesystemNode::dirExists(const string& path)
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA attr;
|
||||
TCHAR unicodeString[MAX_PATH];
|
||||
string tmp(path);
|
||||
if (tmp.at(path.size()-1) == '\\')
|
||||
tmp.resize(path.size()-1);
|
||||
MultiByteToWideChar(CP_ACP, 0, tmp.c_str(), strlen(path.c_str()) + 1, unicodeString, sizeof(unicodeString));
|
||||
|
||||
BOOL b = GetFileAttributesEx(unicodeString, GetFileExInfoStandard, &attr);
|
||||
|
||||
return ((b != 0) && (attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool AbstractFilesystemNode::makeDir(const string& path)
|
||||
{
|
||||
TCHAR unicodeString[MAX_PATH];
|
||||
string tmp(path);
|
||||
if (tmp.at(path.size()-1) == '\\')
|
||||
tmp.resize(path.size()-1);
|
||||
MultiByteToWideChar(CP_ACP, 0, tmp.c_str(), strlen(path.c_str()) + 1, unicodeString, sizeof(unicodeString));
|
||||
|
||||
return CreateDirectory(unicodeString, NULL) != 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool AbstractFilesystemNode::rename(const string& oldpath,
|
||||
const string& newpath)
|
||||
{
|
||||
// TODO - implement this
|
||||
return false;
|
||||
}
|
|
@ -1,990 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// Windows CE Port by Kostas Nakos
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#include <windows.h>
|
||||
#include "FrameBufferWinCE.hxx"
|
||||
#include "Console.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "Font.hxx"
|
||||
|
||||
#define OPTPIXAVERAGE(pix1,pix2) ( ((((pix1 & optgreenmaskN) + (pix2 & optgreenmaskN)) >> 1) & optgreenmaskN) | ((((pix1 & optgreenmask) + (pix2 & optgreenmask)) >> 1) & optgreenmask) )
|
||||
|
||||
FrameBufferWinCE::FrameBufferWinCE(OSystem *osystem): FrameBuffer(osystem),
|
||||
myDstScreen(NULL), SubsystemInited(false), displacement(0), issquare(false),
|
||||
issmartphone(true), islandscape(false), legacygapi(true), devres(SM_LOW), screenlocked(false)
|
||||
{
|
||||
gxdp.cxWidth = gxdp.cyHeight = gxdp.cbxPitch = gxdp.cbyPitch = gxdp.cBPP = gxdp.ffFormat = 0;
|
||||
displaymode = myOSystem->settings().getInt("wince_orientation");
|
||||
if (displaymode > 2) displaymode = 0;
|
||||
}
|
||||
|
||||
FrameBufferWinCE::~FrameBufferWinCE()
|
||||
{
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::GetDeviceProperties(void)
|
||||
{
|
||||
if (gxdp.cxWidth) return;
|
||||
|
||||
// screen access mode
|
||||
gxdp = GXGetDisplayProperties();
|
||||
legacygapi = true;
|
||||
if (((unsigned int) GetSystemMetrics(SM_CXSCREEN) != gxdp.cxWidth) || ((unsigned int) GetSystemMetrics(SM_CYSCREEN) != gxdp.cyHeight))
|
||||
{
|
||||
// 2003SE+ and lying about the resolution. good luck.
|
||||
legacygapi = false;
|
||||
|
||||
RawFrameBufferInfo rfbi;
|
||||
HDC hdc = GetDC(NULL);
|
||||
ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi);
|
||||
ReleaseDC(NULL, hdc);
|
||||
|
||||
if (rfbi.wFormat == FORMAT_565)
|
||||
gxdp.ffFormat = kfDirect565;
|
||||
else if (rfbi.wFormat == FORMAT_555)
|
||||
gxdp.ffFormat = kfDirect555;
|
||||
else
|
||||
gxdp.ffFormat = 0;
|
||||
gxdp.cBPP = rfbi.wBPP;
|
||||
gxdp.cbxPitch = rfbi.cxStride;
|
||||
gxdp.cbyPitch = rfbi.cyStride;
|
||||
gxdp.cxWidth = rfbi.cxPixels;
|
||||
gxdp.cyHeight = rfbi.cyPixels;
|
||||
}
|
||||
|
||||
// device detection (some redundancy here, but nevermind :)
|
||||
TCHAR platform[100];
|
||||
issmartphone = false;
|
||||
if (gxdp.cxWidth == 176 && gxdp.cyHeight == 220)
|
||||
issmartphone = true;
|
||||
if (SystemParametersInfo(SPI_GETPLATFORMTYPE, 100, platform, 0))
|
||||
{
|
||||
if (wcsstr(platform, _T("mart")))
|
||||
issmartphone = true;
|
||||
}
|
||||
else
|
||||
issmartphone = true; // most likely
|
||||
|
||||
if (gxdp.cxWidth == 176 && gxdp.cyHeight == 220)
|
||||
devres = SM_LOW;
|
||||
else if (gxdp.cxWidth == 480 && gxdp.cyHeight == 640)
|
||||
devres = VGA;
|
||||
else
|
||||
{
|
||||
devres = QVGA;
|
||||
// as a special case, qvga landscape devices are represented by the combination of:
|
||||
// devres=QVGA && islandscape=true && displaymode=0
|
||||
if (gxdp.cxWidth > gxdp.cyHeight)
|
||||
islandscape = true;
|
||||
// square QVGA (240x240) devices are portrait, landscape (as above) and square
|
||||
else if (gxdp.cxWidth == gxdp.cyHeight)
|
||||
issquare = islandscape = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::setTIAPalette(const uInt32* palette)
|
||||
{
|
||||
GetDeviceProperties();
|
||||
for (uInt16 i=0; i<256; i++)
|
||||
{
|
||||
uInt8 r = (uInt8) ((palette[i] & 0xFF0000) >> 16);
|
||||
uInt8 g = (uInt8) ((palette[i] & 0x00FF00) >> 8);
|
||||
uInt8 b = (uInt8) (palette[i] & 0x0000FF);
|
||||
if(gxdp.ffFormat & kfDirect565)
|
||||
pal[i] = (uInt16) ( ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3) );
|
||||
else if(gxdp.ffFormat & kfDirect555)
|
||||
pal[i] = (uInt16) ( ((r & 0xF8) << 7) | ((g & 0xF8) << 3) | ((b & 0xF8) >> 3) );
|
||||
else
|
||||
return;
|
||||
paldouble[i] = pal[i] | (pal[i] << 16);
|
||||
}
|
||||
SubsystemInited = false;
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::setUIPalette(const uInt32* palette)
|
||||
{
|
||||
GetDeviceProperties();
|
||||
for (int i=0; i<kNumColors - 256; i++)
|
||||
{
|
||||
uInt8 r = (uInt8) ((palette[i] & 0xFF0000) >> 16);
|
||||
uInt8 g = (uInt8) ((palette[i] & 0x00FF00) >> 8);
|
||||
uInt8 b = (uInt8) (palette[i] & 0x0000FF);
|
||||
if(gxdp.ffFormat & kfDirect565)
|
||||
pal[i+256] = (uInt16) ( ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3) );
|
||||
else if(gxdp.ffFormat & kfDirect555)
|
||||
pal[i+256] = (uInt16) ( ((r & 0xF8) << 7) | ((g & 0xF8) << 3) | ((b & 0xF8) >> 3) );
|
||||
else
|
||||
return;
|
||||
paldouble[i+256] = pal[i+256] | (pal[i+256] << 16);
|
||||
}
|
||||
SubsystemInited = false;
|
||||
}
|
||||
|
||||
bool FrameBufferWinCE::initSubsystem()
|
||||
{
|
||||
static bool firsttime = true;
|
||||
|
||||
GetDeviceProperties();
|
||||
|
||||
// we need to modify our basedim rect in order to center the ingame menu properly
|
||||
// this is, more or less, a hack
|
||||
if (IsSmartphoneLowRes())
|
||||
{
|
||||
myBaseDim.w = 220;
|
||||
myBaseDim.h = 176;
|
||||
}
|
||||
else if (issquare)
|
||||
{
|
||||
myBaseDim.w = 240;
|
||||
myBaseDim.h = 240;
|
||||
}
|
||||
|
||||
// screen extents
|
||||
if(gxdp.ffFormat & kfDirect565)
|
||||
{
|
||||
optgreenmask = 0x7E0;
|
||||
optgreenmaskN = 0xF81F;
|
||||
}
|
||||
else
|
||||
{
|
||||
optgreenmask = 0x3E0;
|
||||
optgreenmaskN = 0x7C1F;
|
||||
}
|
||||
|
||||
scrwidth = gxdp.cxWidth;
|
||||
scrheight = gxdp.cyHeight;
|
||||
scrpixelstep = gxdp.cbxPitch;
|
||||
scrlinestep = gxdp.cbyPitch;
|
||||
|
||||
setmode(displaymode);
|
||||
if (!firsttime)
|
||||
wipescreen(true); // hold the 'initializing' screen on startup
|
||||
firsttime = false;
|
||||
SubsystemInited = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::setmode(uInt8 mode)
|
||||
{
|
||||
bool qvga_l = (displaymode == 0) && islandscape;
|
||||
|
||||
displaymode = mode % 3;
|
||||
switch (displaymode)
|
||||
{
|
||||
// portrait
|
||||
case 0:
|
||||
pixelstep = gxdp.cbxPitch;
|
||||
linestep = gxdp.cbyPitch;
|
||||
break;
|
||||
|
||||
// landscape
|
||||
case 1:
|
||||
pixelstep = - gxdp.cbyPitch;
|
||||
linestep = gxdp.cbxPitch;
|
||||
break;
|
||||
|
||||
// inverted landscape
|
||||
case 2:
|
||||
pixelstep = gxdp.cbyPitch;
|
||||
linestep = - gxdp.cbxPitch;
|
||||
break;
|
||||
}
|
||||
islandscape = displaymode || qvga_l;
|
||||
|
||||
pixelstepdouble = pixelstep << 1;
|
||||
linestepdouble = linestep << 1;
|
||||
pixelsteptimes5 = pixelstep * 5;
|
||||
pixelsteptimes6 = pixelstep * 6;
|
||||
pixelsteptimes8 = pixelstep * 8;
|
||||
pixelsteptimes12 = pixelstep * 12;
|
||||
pixelsteptimes16 = pixelstep * 16;
|
||||
SubsystemInited = false;
|
||||
}
|
||||
|
||||
uInt8 FrameBufferWinCE::rotatedisplay(void)
|
||||
{
|
||||
if (!(displaymode == 0 && islandscape))
|
||||
{
|
||||
islandscape = false;
|
||||
displaymode = (displaymode + 1) % 3;
|
||||
}
|
||||
setmode(displaymode);
|
||||
wipescreen();
|
||||
myOSystem->settings().setInt("wince_orientation", displaymode);
|
||||
return displaymode;
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::lateinit(void)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
myWidth = myOSystem->console().mediaSource().width();
|
||||
myHeight = myOSystem->console().mediaSource().height();
|
||||
myWidthdiv4 = myWidth >> 2;
|
||||
|
||||
if (devres == SM_LOW)
|
||||
if (!islandscape)
|
||||
w = myWidth;
|
||||
else
|
||||
w = (int) ((float) myWidth * 11.0f / 8.0f + 0.5f);
|
||||
else if (devres == QVGA)
|
||||
if (!islandscape && !issquare)
|
||||
w = (int) ((float) myWidth * 3.0f / 2.0f + 0.5f);
|
||||
else
|
||||
w = myWidth * 2;
|
||||
else
|
||||
{
|
||||
if (!islandscape)
|
||||
w = (int) ((float) myWidth * 3.0f + 0.5f);
|
||||
else
|
||||
w = myWidth * 4;
|
||||
}
|
||||
|
||||
if (devres == SM_LOW && islandscape)
|
||||
h = (int) ((float) myHeight * 4.0f / 5.0f + 0.5f);
|
||||
else if (devres == VGA)
|
||||
h = myHeight * 2;
|
||||
else
|
||||
h = myHeight;
|
||||
|
||||
switch (displaymode)
|
||||
{
|
||||
case 0:
|
||||
if (scrwidth > w)
|
||||
displacement = (scrwidth - w) / 2 * gxdp.cbxPitch;
|
||||
else
|
||||
displacement = 0;
|
||||
if (scrheight > h)
|
||||
{
|
||||
displacement += (scrheight - h) / 2 * gxdp.cbyPitch;
|
||||
minydim = h;
|
||||
}
|
||||
else
|
||||
minydim = scrheight;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
displacement = gxdp.cbyPitch*(gxdp.cyHeight-1);
|
||||
if (scrwidth > h)
|
||||
{
|
||||
minydim = h;
|
||||
displacement += (scrwidth - h) / 2 * gxdp.cbxPitch;
|
||||
}
|
||||
else
|
||||
minydim = scrwidth;
|
||||
if (scrheight > w)
|
||||
displacement -= (scrheight - w) / 2 * gxdp.cbyPitch;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
displacement = gxdp.cbxPitch*(gxdp.cxWidth-1);
|
||||
if (scrwidth > h)
|
||||
{
|
||||
minydim = h;
|
||||
displacement -= (scrwidth - h) / 2 * gxdp.cbxPitch;
|
||||
}
|
||||
else
|
||||
minydim = scrwidth;
|
||||
if (scrheight > w)
|
||||
displacement += (scrheight - w) / 2 * gxdp.cbyPitch;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (devres == VGA)
|
||||
{
|
||||
minydim >>= 1;
|
||||
displacement &= ~3; // ensure longword alignment
|
||||
}
|
||||
|
||||
SubsystemInited = true;
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::preFrameUpdate()
|
||||
{
|
||||
static HDC hdc;
|
||||
static RawFrameBufferInfo rfbi;
|
||||
|
||||
if (screenlocked)
|
||||
return;
|
||||
|
||||
if (legacygapi)
|
||||
myDstScreen = (uInt8 *) GXBeginDraw();
|
||||
else
|
||||
{
|
||||
hdc = GetDC(NULL);
|
||||
ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi);
|
||||
ReleaseDC(NULL, hdc);
|
||||
myDstScreen = (uInt8 *) rfbi.pFramePointer;
|
||||
}
|
||||
|
||||
screenlocked = true;
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::drawMediaSource()
|
||||
{
|
||||
static uInt8 *sc, *sp, *sc_n, *sp_n;
|
||||
static uInt8 *d, *pl, *nl;
|
||||
static uInt16 pix1, pix2, pix3, x, y;
|
||||
uInt32 pix1d, pix2d, pix3d;
|
||||
|
||||
if (!SubsystemInited)
|
||||
lateinit();
|
||||
|
||||
if ( (d = myDstScreen) == NULL )
|
||||
return;
|
||||
|
||||
d += displacement;
|
||||
pl = d;
|
||||
sc = myOSystem->console().mediaSource().currentFrameBuffer();
|
||||
sp = myOSystem->console().mediaSource().previousFrameBuffer();
|
||||
|
||||
if (theRedrawTIAIndicator)
|
||||
{
|
||||
memset(sp, 0, myWidth*myHeight-1);
|
||||
memset(myDstScreen, 0, scrwidth*scrheight*2);
|
||||
theRedrawTIAIndicator = false;
|
||||
}
|
||||
|
||||
if (devres == SM_LOW && !islandscape)
|
||||
{
|
||||
// straight
|
||||
for (y=0; y<minydim; y++)
|
||||
{
|
||||
for (x=0; x<myWidthdiv4; x++)
|
||||
{
|
||||
if ( *((uInt32 *) sc) != *((uInt32 *) sp) )
|
||||
{
|
||||
*((uInt16 *)d) = pal[*sc++]; d += pixelstep;
|
||||
*((uInt16 *)d) = pal[*sc++]; d += pixelstep;
|
||||
*((uInt16 *)d) = pal[*sc++]; d += pixelstep;
|
||||
*((uInt16 *)d) = pal[*sc++]; d += pixelstep;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc += 4;
|
||||
d += (pixelstep << 2);
|
||||
}
|
||||
sp += 4;
|
||||
}
|
||||
d = pl + linestep;
|
||||
pl = d;
|
||||
}
|
||||
}
|
||||
else if (devres == SM_LOW && islandscape)
|
||||
{
|
||||
for (y=0; y<minydim; y++)
|
||||
{
|
||||
// 4/5
|
||||
if ((y & 3) ^ 3)
|
||||
{ // normal line
|
||||
for (x=0; x<myWidthdiv4; x++)
|
||||
{
|
||||
// 11/8
|
||||
// **X**
|
||||
if ( *((uInt32 *) sc) != *((uInt32 *) sp) )
|
||||
{
|
||||
*((uInt16 *)d) = pal[*sc++]; d += pixelstep;
|
||||
pix1 = pal[*sc++]; pix2 = pal[*sc++];
|
||||
*((uInt16 *)d) = pix1; d += pixelstep;
|
||||
*((uInt16 *)d) = OPTPIXAVERAGE(pix1,pix2); d += pixelstep;
|
||||
*((uInt16 *)d) = pix2; d += pixelstep;
|
||||
*((uInt16 *)d) = pal[*sc++]; d += pixelstep;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc += 4;
|
||||
d += pixelsteptimes5;
|
||||
}
|
||||
sp += 4;
|
||||
if (++x>=myWidthdiv4) break;
|
||||
|
||||
// *X**X*
|
||||
if ( *((uInt32 *) sc) != *((uInt32 *) sp) )
|
||||
{
|
||||
pix1 = pal[*sc++]; pix2 = pal[*sc++];
|
||||
*((uInt16 *)d) = pix1; d += pixelstep;
|
||||
*((uInt16 *)d) = OPTPIXAVERAGE(pix1,pix2); d += pixelstep;
|
||||
*((uInt16 *)d) = pix2; d += pixelstep;
|
||||
pix1 = pal[*sc++]; pix2 = pal[*sc++];
|
||||
*((uInt16 *)d) = pix1; d += pixelstep;
|
||||
*((uInt16 *)d) = OPTPIXAVERAGE(pix1,pix2); d += pixelstep;
|
||||
*((uInt16 *)d) = pix2; d += pixelstep;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc += 4;
|
||||
d += pixelsteptimes6;
|
||||
}
|
||||
sp += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // skipped line
|
||||
sc_n = sc + myWidth;
|
||||
sp_n = sp + myWidth;
|
||||
for (x=0; x<myWidthdiv4; x++)
|
||||
{
|
||||
// 11/8
|
||||
// **X**
|
||||
if ( (*((uInt32 *) sc) != *((uInt32 *) sp)) || (*((uInt32 *) sc_n) != *((uInt32 *) sp_n)) )
|
||||
{
|
||||
pix1 = pal[*sc++]; pix2 = pal[*sc_n++];
|
||||
*((uInt16 *)d) = OPTPIXAVERAGE(pix1,pix2); d += pixelstep;
|
||||
pix1 = pal[*sc++]; pix2 = pal[*sc_n++];
|
||||
pix1 = OPTPIXAVERAGE(pix1,pix2);
|
||||
*((uInt16 *)d) = pix1; d += pixelstep;
|
||||
pix2 = pal[*sc++]; pix3 = pal[*sc_n++];
|
||||
pix2 = OPTPIXAVERAGE(pix2,pix3);
|
||||
pix3 = OPTPIXAVERAGE(pix1,pix2);
|
||||
*((uInt16 *)d) = pix3; d += pixelstep;
|
||||
*((uInt16 *)d) = pix2; d += pixelstep;
|
||||
pix1 = pal[*sc++]; pix2 = pal[*sc_n++];
|
||||
*((uInt16 *)d) = OPTPIXAVERAGE(pix1,pix2); d += pixelstep;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc += 4;
|
||||
sc_n += 4;
|
||||
d += pixelsteptimes5;
|
||||
}
|
||||
sp += 4;
|
||||
sp_n += 4;
|
||||
if (++x>=myWidthdiv4) break;
|
||||
|
||||
// *X**X*
|
||||
if ( (*((uInt32 *) sc) != *((uInt32 *) sp)) || (*((uInt32 *) sc_n) != *((uInt32 *) sp_n)) )
|
||||
{
|
||||
pix1 = pal[*sc++]; pix2 = pal[*sc_n++];
|
||||
pix1 = OPTPIXAVERAGE(pix1,pix2);
|
||||
*((uInt16 *)d) = pix1; d += pixelstep;
|
||||
pix2 = pal[*sc++]; pix3 = pal[*sc_n++];
|
||||
pix2 = OPTPIXAVERAGE(pix2,pix3);
|
||||
pix3 = OPTPIXAVERAGE(pix1,pix2);
|
||||
*((uInt16 *)d) = pix3; d += pixelstep;
|
||||
*((uInt16 *)d) = pix2; d += pixelstep;
|
||||
pix1 = pal[*sc++]; pix2 = pal[*sc_n++];
|
||||
pix1 = OPTPIXAVERAGE(pix1,pix2);
|
||||
*((uInt16 *)d) = pix1; d += pixelstep;
|
||||
pix2 = pal[*sc++]; pix3 = pal[*sc_n++];
|
||||
pix2 = OPTPIXAVERAGE(pix2,pix3);
|
||||
pix3 = OPTPIXAVERAGE(pix1,pix2);
|
||||
*((uInt16 *)d) = pix3; d += pixelstep;
|
||||
*((uInt16 *)d) = pix2; d += pixelstep;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc += 4;
|
||||
sc_n += 4;
|
||||
d += pixelsteptimes6;
|
||||
}
|
||||
sp += 4;
|
||||
sp_n += 4;
|
||||
}
|
||||
sc += myWidth;
|
||||
sp += myWidth;
|
||||
}
|
||||
d = pl + linestep;
|
||||
pl = d;
|
||||
}
|
||||
}
|
||||
else if (devres == QVGA && (!islandscape || issquare))
|
||||
{
|
||||
// 3/2
|
||||
for (y=0; y<minydim; y++)
|
||||
{
|
||||
for (x=0; x<myWidthdiv4; x++)
|
||||
{
|
||||
if ( *((uInt32 *) sc) != *((uInt32 *) sp) )
|
||||
{
|
||||
pix1 = pal[*sc++]; pix2 = pal[*sc++];
|
||||
*((uInt16 *)d) = pix1; d += pixelstep;
|
||||
*((uInt16 *)d) = OPTPIXAVERAGE(pix1,pix2); d += pixelstep;
|
||||
*((uInt16 *)d) = pix2; d += pixelstep;
|
||||
pix1 = pal[*sc++]; pix2 = pal[*sc++];
|
||||
*((uInt16 *)d) = pix1; d += pixelstep;
|
||||
*((uInt16 *)d) = OPTPIXAVERAGE(pix1,pix2); d += pixelstep;
|
||||
*((uInt16 *)d) = pix2; d += pixelstep;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc += 4;
|
||||
d += pixelsteptimes6;
|
||||
}
|
||||
sp += 4;
|
||||
}
|
||||
d = pl + linestep;
|
||||
pl = d;
|
||||
}
|
||||
}
|
||||
else if (devres == QVGA && islandscape)
|
||||
{
|
||||
// 2/1
|
||||
for (y=0; y<minydim; y++)
|
||||
{
|
||||
for (x=0; x<myWidthdiv4; x++)
|
||||
{
|
||||
if ( *((uInt32 *) sc) != *((uInt32 *) sp) )
|
||||
{
|
||||
pix1 = pal[*sc++]; pix2 = pal[*sc++];
|
||||
*((uInt16 *)d) = pix1; d += pixelstep;
|
||||
*((uInt16 *)d) = OPTPIXAVERAGE(pix1,pix2); d += pixelstep;
|
||||
pix1 = pal[*sc++];
|
||||
*((uInt16 *)d) = pix2; d += pixelstep;
|
||||
*((uInt16 *)d) = OPTPIXAVERAGE(pix1,pix2); d += pixelstep;
|
||||
pix2 = pal[*sc++];
|
||||
*((uInt16 *)d) = pix1; d += pixelstep;
|
||||
*((uInt16 *)d) = OPTPIXAVERAGE(pix1,pix2); d += pixelstep;
|
||||
*((uInt16 *)d) = pix2; d += pixelstep;
|
||||
*((uInt16 *)d) = pix2; d += pixelstep;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc += 4;
|
||||
d += pixelsteptimes8;
|
||||
}
|
||||
sp += 4;
|
||||
}
|
||||
d = pl + linestep;
|
||||
pl = d;
|
||||
}
|
||||
}
|
||||
else if (devres == VGA && !islandscape)
|
||||
{
|
||||
for (y=0; y<minydim; y++)
|
||||
{
|
||||
// 2/1
|
||||
for (x=0; x<myWidthdiv4; x++)
|
||||
{
|
||||
// 3/1
|
||||
if ( *((uInt32 *) sc) != *((uInt32 *) sp) )
|
||||
{
|
||||
nl = d + linestep;
|
||||
pix1d = paldouble[*sc++]; pix2d = paldouble[*sc++];
|
||||
*((uInt32 *)d) = pix1d; d += pixelstepdouble;
|
||||
*((uInt32 *)nl) = pix1d; nl += pixelstepdouble;
|
||||
pix3d = ((uInt16) pix1d) | (((uInt16) pix2d) << 16);
|
||||
*((uInt32 *)d) = pix3d; d += pixelstepdouble;
|
||||
*((uInt32 *)nl) = pix3d; nl += pixelstepdouble;
|
||||
*((uInt32 *)d) = pix2d; d += pixelstepdouble;
|
||||
*((uInt32 *)nl) = pix2d; nl += pixelstepdouble;
|
||||
pix1d = paldouble[*sc++]; pix2d = paldouble[*sc++];
|
||||
*((uInt32 *)d) = pix1d; d += pixelstepdouble;
|
||||
*((uInt32 *)nl) = pix1d; nl += pixelstepdouble;
|
||||
pix3d = ((uInt16) pix1d) | (((uInt16) pix2d) << 16);
|
||||
*((uInt32 *)d) = pix3d; d += pixelstepdouble;
|
||||
*((uInt32 *)nl) = pix3d; nl += pixelstepdouble;
|
||||
*((uInt32 *)d) = pix2d; d += pixelstepdouble;
|
||||
*((uInt32 *)nl) = pix2d;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc += 4;
|
||||
d += pixelsteptimes12;
|
||||
}
|
||||
sp += 4;
|
||||
}
|
||||
d = pl + linestepdouble;
|
||||
pl = d;
|
||||
}
|
||||
}
|
||||
else if (devres == VGA && islandscape)
|
||||
{
|
||||
for (y=0; y<minydim; y++)
|
||||
{
|
||||
// 2/1
|
||||
for (x=0; x<myWidthdiv4; x++)
|
||||
{
|
||||
// 4/1
|
||||
if ( *((uInt32 *) sc) != *((uInt32 *) sp) )
|
||||
{
|
||||
nl = d + pixelstep;
|
||||
pix1d = paldouble[*sc++];
|
||||
*((uInt32 *)d) = pix1d; d += pixelstepdouble;
|
||||
*((uInt32 *)nl) = pix1d; nl += pixelstepdouble;
|
||||
*((uInt32 *)d) = pix1d; d += pixelstepdouble;
|
||||
*((uInt32 *)nl) = pix1d; nl += pixelstepdouble;
|
||||
pix1d = paldouble[*sc++];
|
||||
*((uInt32 *)d) = pix1d; d += pixelstepdouble;
|
||||
*((uInt32 *)nl) = pix1d; nl += pixelstepdouble;
|
||||
*((uInt32 *)d) = pix1d; d += pixelstepdouble;
|
||||
*((uInt32 *)nl) = pix1d; nl += pixelstepdouble;
|
||||
pix1d = paldouble[*sc++];
|
||||
*((uInt32 *)d) = pix1d; d += pixelstepdouble;
|
||||
*((uInt32 *)nl) = pix1d; nl += pixelstepdouble;
|
||||
*((uInt32 *)d) = pix1d; d += pixelstepdouble;
|
||||
*((uInt32 *)nl) = pix1d; nl += pixelstepdouble;
|
||||
pix1d = paldouble[*sc++];
|
||||
*((uInt32 *)d) = pix1d; d += pixelstepdouble;
|
||||
*((uInt32 *)nl) = pix1d; nl += pixelstepdouble;
|
||||
*((uInt32 *)d) = pix1d; d += pixelstepdouble;
|
||||
*((uInt32 *)nl) = pix1d;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc += 4;
|
||||
d += pixelsteptimes16;
|
||||
}
|
||||
sp += 4;
|
||||
}
|
||||
d = pl + linestepdouble;
|
||||
pl = d;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::wipescreen(bool atinit)
|
||||
{
|
||||
if (!atinit)
|
||||
{
|
||||
if (!SubsystemInited)
|
||||
lateinit();
|
||||
|
||||
uInt8 *s = myOSystem->console().mediaSource().currentFrameBuffer();
|
||||
memset(s, 0, myWidth*myHeight-1);
|
||||
s = myOSystem->console().mediaSource().previousFrameBuffer();
|
||||
memset(s, 0, myWidth*myHeight-1);
|
||||
}
|
||||
|
||||
preFrameUpdate();
|
||||
memset(myDstScreen, 0, scrwidth*scrheight*2);
|
||||
postFrameUpdate();
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::postFrameUpdate()
|
||||
{
|
||||
if (!screenlocked) return;
|
||||
if (legacygapi) GXEndDraw();
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::drawChar(const GUI::Font* myfont, uInt8 c, uInt32 x, uInt32 y, int color)
|
||||
{
|
||||
const FontDesc& desc = myfont->desc();
|
||||
|
||||
if (!myDstScreen) return;
|
||||
|
||||
if (c < desc.firstchar || c >= desc.firstchar + desc.size)
|
||||
{
|
||||
if (c == ' ')
|
||||
return;
|
||||
c = desc.defaultchar;
|
||||
}
|
||||
|
||||
Int32 w = myfont->getCharWidth(c);
|
||||
const Int32 h = myfont->getFontHeight();
|
||||
c -= desc.firstchar;
|
||||
const uInt16* tmp = desc.bits + (desc.offset ? desc.offset[c] : (c * h));
|
||||
|
||||
if ((Int32)x<0 || (Int32)y<0 || (x>>1)+w>scrwidth || y+h>scrheight) return;
|
||||
|
||||
uInt8 *d;
|
||||
if (devres != VGA)
|
||||
{
|
||||
if (!displaymode && islandscape)
|
||||
d = myDstScreen + y * scrlinestep + x * scrpixelstep;
|
||||
else if (displaymode != 2)
|
||||
d = myDstScreen + (scrheight-x) * scrlinestep + y * scrpixelstep;
|
||||
else
|
||||
d = myDstScreen + x * scrlinestep + (scrwidth-y) * scrpixelstep;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (displaymode != 2)
|
||||
d = myDstScreen + ((scrheight>>1)-x-1) * (scrlinestep<<1) + y * (scrpixelstep << 1);
|
||||
else
|
||||
d = myDstScreen + x * (scrlinestep<<1) + ((scrwidth>>1)-y) * (scrpixelstep<<1);
|
||||
}
|
||||
|
||||
uInt16 col = pal[color];
|
||||
uInt32 cold = paldouble[color];
|
||||
|
||||
for (int y2 = 0; y2 < h; y2++)
|
||||
{
|
||||
const uInt16 buffer = *tmp++;
|
||||
if (devres != VGA)
|
||||
{
|
||||
uInt16 mask = 0x8000;
|
||||
uInt8 *tmp = d;
|
||||
for (int x2 = 0; x2 < w; x2++, mask >>= 1)
|
||||
{
|
||||
if (buffer & mask)
|
||||
*((uInt16 *)d) = col;
|
||||
if (!displaymode && islandscape)
|
||||
d += scrpixelstep;
|
||||
else if (displaymode != 2)
|
||||
d -= scrlinestep;
|
||||
else
|
||||
d += scrlinestep;
|
||||
}
|
||||
if (!displaymode && islandscape)
|
||||
d = tmp + scrlinestep;
|
||||
else if (displaymode != 2)
|
||||
d = tmp + scrpixelstep;
|
||||
else
|
||||
d = tmp - scrpixelstep;
|
||||
}
|
||||
else
|
||||
{
|
||||
uInt16 mask = 0x8000;
|
||||
uInt8 *tmp = d;
|
||||
for (int x2 = 0; x2 < w; x2++, mask >>= 1)
|
||||
{
|
||||
if (buffer & mask)
|
||||
{
|
||||
*((uInt32 *)d) = cold;
|
||||
*((uInt32 *)(d+scrlinestep)) = cold;
|
||||
}
|
||||
if (displaymode != 2)
|
||||
d -= (scrlinestep<<1);
|
||||
else
|
||||
d += (scrlinestep<<1);
|
||||
}
|
||||
if (displaymode != 2)
|
||||
d = tmp + (scrpixelstep<<1);
|
||||
else
|
||||
d = tmp - (scrpixelstep<<1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::hLine(uInt32 x, uInt32 y, uInt32 x2, int color)
|
||||
{
|
||||
if (devres != VGA)
|
||||
if (!displaymode && islandscape)
|
||||
PlothLine(x, y, x2, color);
|
||||
else if (displaymode != 2)
|
||||
PlotvLine(y, scrheight-x, scrheight-x2, color);
|
||||
else
|
||||
PlotvLine(scrwidth-y, x, x2, color);
|
||||
else
|
||||
if (displaymode != 2)
|
||||
{
|
||||
PlotvLine((y<<1), (((scrheight>>1)-x)<<1)-1, (((scrheight>>1)-x2)<<1)-1, color);
|
||||
PlotvLine((y<<1)+1, (((scrheight>>1)-x)<<1)-1, (((scrheight>>1)-x2)<<1)-1, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
PlotvLine(((scrwidth>>1)-y)<<1, x<<1, x2<<1, color);
|
||||
PlotvLine((((scrwidth>>1)-y)<<1)+1, x<<1, x2<<1, color);
|
||||
}
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::PlothLine(uInt32 x, uInt32 y, uInt32 x2, int color)
|
||||
{
|
||||
if (!myDstScreen) return;
|
||||
if (x>x2) { x2 ^= x; x ^= x2; x2 ^= x;} //lazy swap
|
||||
uInt8 *d = myDstScreen + y * scrlinestep + x * scrpixelstep;
|
||||
uInt16 col = pal[color];
|
||||
for (;x <= x2; x++, *((uInt16 *)d) = col, d += scrpixelstep);
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::vLine(uInt32 x, uInt32 y, uInt32 y2, int color)
|
||||
{
|
||||
if (devres != VGA)
|
||||
if (!displaymode && islandscape)
|
||||
PlotvLine(x, y, y2, color);
|
||||
else if (displaymode != 2)
|
||||
PlothLine(y, scrheight-x, y2, color);
|
||||
else
|
||||
PlothLine(scrwidth-y, x, scrwidth-y2, color);
|
||||
else
|
||||
if (displaymode != 2)
|
||||
{
|
||||
PlothLine(y<<1, (((scrheight>>1)-x)<<1)-2, y2<<1, color);
|
||||
PlothLine(y<<1, (((scrheight>>1)-x)<<1)-1, y2<<1, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
PlothLine(((scrwidth>>1)-y)<<1, x<<1, ((scrwidth>>1)-y2)<<1, color);
|
||||
PlothLine(((scrwidth>>1)-y)<<1, (x<<1)+1, ((scrwidth>>1)-y2)<<1, color);
|
||||
}
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::PlotvLine(uInt32 x, uInt32 y, uInt32 y2, int color)
|
||||
{
|
||||
if (y>y2) { y2 ^= y; y ^= y2; y2 ^= y;} //lazy swap
|
||||
if (!myDstScreen) return;
|
||||
uInt8 *d = myDstScreen + y * scrlinestep + x * scrpixelstep;
|
||||
uInt16 col = pal[color];
|
||||
for (;y <= y2; y++, *((uInt16 *)d) = col, d += scrlinestep);
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, int color)
|
||||
{
|
||||
if (w==0 || h==0) return;
|
||||
if (devres != VGA)
|
||||
{
|
||||
if (!displaymode && islandscape)
|
||||
{
|
||||
PlotfillRect(x, y, w, h, color);
|
||||
return;
|
||||
}
|
||||
if (x>scrheight) return; if (y>scrwidth) return;
|
||||
if (x+w>scrheight) w=scrheight-x; if (y+h>scrwidth) h=scrwidth-y;
|
||||
if (displaymode != 2)
|
||||
PlotfillRect(y, scrheight-x-w+1, h, w, color);
|
||||
else
|
||||
PlotfillRect(scrwidth-y-h+1, x, h, w, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((int)x>(scrheight>>1)) return; if ((int)y>(scrwidth>>1)) return;
|
||||
if ((int)(x+w)>(scrheight>>1)) w=(scrheight>>1)-x; if ((int)(y+h)>(scrwidth>>1)) h=(scrwidth>>1)-y;
|
||||
if (displaymode != 2)
|
||||
PlotfillRect(y<<1, (((scrheight>>1)-x-w+1)<<1)-2, h<<1, w<<1, color);
|
||||
else
|
||||
PlotfillRect(((scrwidth>>1)-y-h+1)<<1, x<<1, h<<1, w<<1, color);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::PlotfillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, int color)
|
||||
{
|
||||
if (!myDstScreen) return;
|
||||
uInt8 *d = myDstScreen + y * scrlinestep + x * scrpixelstep;
|
||||
uInt16 col = pal[color];
|
||||
uInt32 stride = (scrwidth - w) * scrpixelstep;
|
||||
for (;h != 0; h--, d += stride)
|
||||
for (int w2=w; w2>0; w2--, *((uInt16 *)d) = col, d += scrpixelstep);
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::drawBitmap(uInt32* bitmap, Int32 x, Int32 y, int color, Int32 h)
|
||||
{
|
||||
uInt8 *d;
|
||||
uInt16 col;
|
||||
uInt32 cold;
|
||||
|
||||
if (!myDstScreen) return;
|
||||
|
||||
if (devres != VGA)
|
||||
if (!displaymode && islandscape)
|
||||
d = myDstScreen + y * scrlinestep + x * scrpixelstep;
|
||||
else if (displaymode != 2)
|
||||
d = myDstScreen + (scrheight-x) * scrlinestep + y * scrpixelstep;
|
||||
else
|
||||
d = myDstScreen + x * scrlinestep + (scrwidth-y) * scrpixelstep;
|
||||
else
|
||||
if (displaymode != 2)
|
||||
d = myDstScreen + ((scrheight>>1)-x-1) * (scrlinestep<<1) + y * (scrpixelstep<<1);
|
||||
else
|
||||
d = myDstScreen + x * (scrlinestep<<1) + ((scrwidth>>1)-y) * (scrpixelstep<<1);
|
||||
|
||||
col = pal[color];
|
||||
cold = paldouble[color];
|
||||
for (int i = 0; i < h; i++)
|
||||
{
|
||||
uInt32 mask = 0xF0000000;
|
||||
uInt8 *tmp = d;
|
||||
|
||||
for (int j = 0; j < 8; j++, mask >>= 4)
|
||||
{
|
||||
if(bitmap[i] & mask)
|
||||
{
|
||||
if (devres != VGA)
|
||||
*((uInt16 *)d) = col;
|
||||
else
|
||||
{
|
||||
*((uInt32 *)d) = cold;
|
||||
*((uInt32 *)(d+scrlinestep)) = cold;
|
||||
}
|
||||
}
|
||||
if (devres != VGA)
|
||||
{
|
||||
if (!displaymode && islandscape)
|
||||
d += scrpixelstep;
|
||||
else if (displaymode != 2)
|
||||
d -= scrlinestep;
|
||||
else
|
||||
d += scrlinestep;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (displaymode != 2)
|
||||
d -= (scrlinestep<<1);
|
||||
else
|
||||
d += (scrlinestep<<1);
|
||||
}
|
||||
}
|
||||
|
||||
if (devres != VGA)
|
||||
{
|
||||
if (!displaymode && islandscape)
|
||||
d = tmp + scrlinestep;
|
||||
else if (displaymode != 2)
|
||||
d = tmp + scrpixelstep;
|
||||
else
|
||||
d = tmp - scrpixelstep;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (displaymode != 2)
|
||||
d = tmp + (scrpixelstep<<1);
|
||||
else
|
||||
d = tmp - (scrpixelstep<<1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::translateCoords(Int32* x, Int32* y)
|
||||
{
|
||||
if ((displaymode == 1) || (displaymode==0 && !islandscape && myOSystem->eventHandler().state() != EventHandler::S_EMULATE))
|
||||
{
|
||||
Int32 x2 = *x;
|
||||
*x = scrheight - *y;
|
||||
*y = x2;
|
||||
}
|
||||
else if (displaymode == 2)
|
||||
{
|
||||
Int32 x2 = *x;
|
||||
*x = *y;
|
||||
*y = scrwidth - x2;
|
||||
}
|
||||
if (devres == VGA)
|
||||
{
|
||||
*x >>= 1;
|
||||
*y >>= 1;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void FrameBufferWinCE::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
|
||||
{
|
||||
static bool initflag = false;
|
||||
|
||||
if (myOSystem->eventHandler().state() == EventHandler::S_MENU)
|
||||
initflag = true;
|
||||
|
||||
if (myOSystem->eventHandler().state() == EventHandler::S_EMULATE && initflag)
|
||||
theRedrawTIAIndicator = true; // TODO: optimize here
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
string FrameBufferWinCE::about()
|
||||
{
|
||||
string id = "Video rendering: ";
|
||||
id += (issmartphone ? "SM " : "PPC ");
|
||||
id += (legacygapi ? "GAPI " : "Direct ");
|
||||
id += (devres == SM_LOW ? "176x220\n" : (devres == QVGA ? "240x320\n" : "480x640\n"));
|
||||
return id;
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// Windows CE Port by Kostas Nakos
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#ifndef FRAMEBUFFER_WINCE_HXX
|
||||
#define FRAMEBUFFER_WINCE_HXX
|
||||
|
||||
#include <gx.h>
|
||||
#include "bspf.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "OSystem.hxx"
|
||||
|
||||
|
||||
// The necessary nonsense for extended resolutions
|
||||
#define GETRAWFRAMEBUFFER 0x00020001
|
||||
|
||||
#define FORMAT_565 1
|
||||
#define FORMAT_555 2
|
||||
#define FORMAT_OTHER 3
|
||||
|
||||
#if _WIN32_WCE <= 300
|
||||
typedef struct _RawFrameBufferInfo
|
||||
{
|
||||
WORD wFormat;
|
||||
WORD wBPP;
|
||||
VOID *pFramePointer;
|
||||
int cxStride;
|
||||
int cyStride;
|
||||
int cxPixels;
|
||||
int cyPixels;
|
||||
} RawFrameBufferInfo;
|
||||
#endif
|
||||
|
||||
class FrameBufferWinCE : public FrameBuffer
|
||||
{
|
||||
public:
|
||||
|
||||
FrameBufferWinCE(OSystem *osystem);
|
||||
~FrameBufferWinCE();
|
||||
virtual void setTIAPalette(const uInt32* palette);
|
||||
virtual void setUIPalette(const uInt32* palette);
|
||||
virtual bool initSubsystem();
|
||||
virtual BufferType type() { return kSoftBuffer; }
|
||||
virtual void setAspectRatio() { return; };
|
||||
virtual bool createScreen() { return true; };
|
||||
virtual void toggleFilter() { return; };
|
||||
virtual void drawMediaSource();
|
||||
virtual void preFrameUpdate();
|
||||
virtual void postFrameUpdate();
|
||||
virtual void scanline(uInt32 row, uInt8* data) { return; };
|
||||
virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b) { return 0xFFFFFFFF; };
|
||||
virtual void hLine(uInt32 x, uInt32 y, uInt32 x2, int color);
|
||||
virtual void vLine(uInt32 x, uInt32 y, uInt32 y2, int color);
|
||||
virtual void fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, int color);
|
||||
virtual void drawChar(const GUI::Font* font, uInt8 c, uInt32 x, uInt32 y, int color);
|
||||
virtual void drawBitmap(uInt32* bitmap, Int32 x, Int32 y, int color, Int32 h = 8);
|
||||
virtual void translateCoords(Int32* x, Int32* y);
|
||||
virtual void addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h);
|
||||
virtual void enablePhosphor(bool enable, int blend) { return; };
|
||||
virtual uInt32 lineDim() { return 1; };
|
||||
virtual string about();
|
||||
virtual void setScaler(Scaler scaler) { return; };
|
||||
void wipescreen(bool atinit=false);
|
||||
void setmode(uInt8 mode);
|
||||
uInt8 rotatedisplay(void);
|
||||
|
||||
private:
|
||||
|
||||
void lateinit(void);
|
||||
void PlothLine(uInt32 x, uInt32 y, uInt32 x2, int color);
|
||||
void PlotvLine(uInt32 x, uInt32 y, uInt32 y2, int color);
|
||||
void PlotfillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, int color);
|
||||
void GetDeviceProperties(void);
|
||||
|
||||
uInt16 pal[256+kNumColors], myWidth, myWidthdiv4, myHeight, scrwidth, scrheight;
|
||||
Int32 pixelstep, pixelstepdouble, linestep, linestepdouble, scrpixelstep, scrlinestep;
|
||||
uInt32 paldouble[256+kNumColors], displacement;
|
||||
bool SubsystemInited;
|
||||
uInt8 *myDstScreen;
|
||||
|
||||
bool issmartphone, islandscape, issquare, legacygapi, screenlocked;
|
||||
enum {SM_LOW, QVGA, VGA} devres;
|
||||
uInt16 minydim, optgreenmaskN, optgreenmask;
|
||||
Int32 pixelsteptimes5, pixelsteptimes6, pixelsteptimes8, pixelsteptimes12, pixelsteptimes16;
|
||||
GXDisplayProperties gxdp;
|
||||
uInt8 displaymode;
|
||||
|
||||
public:
|
||||
bool IsSmartphone(void) { return issmartphone; }
|
||||
bool IsSmartphoneLowRes(void) { return (issmartphone && devres==SM_LOW); }
|
||||
bool IsVGA(void) { return (devres==VGA); }
|
||||
uInt8 getmode(void) { return displaymode; }
|
||||
bool IsLandscape(void) { return islandscape; }
|
||||
void GetScreenExtents(uInt16 *x, uInt16 *y) { *x = scrwidth; *y = scrheight; return; }
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,132 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// Windows CE Port by Kostas Nakos
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "OSystemWinCE.hxx"
|
||||
#include "SoundWinCE.hxx"
|
||||
#include "FrameBufferWinCE.hxx"
|
||||
|
||||
extern bool RequestRefresh;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
OSystemWinCE::OSystemWinCE(const string& path) : OSystem()
|
||||
{
|
||||
setBaseDir(path);
|
||||
setStateDir(path);
|
||||
setPropertiesDir(path);
|
||||
setConfigFile(path + "stella.ini");
|
||||
setCacheFile(path + "stella.cache");
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
OSystemWinCE::~OSystemWinCE()
|
||||
{
|
||||
}
|
||||
|
||||
void OSystemWinCE::setFramerate(uInt32 framerate)
|
||||
{
|
||||
myDisplayFrameRate = framerate;
|
||||
myTimePerFrame = (uInt32)(1000.0 / (double)myDisplayFrameRate);
|
||||
}
|
||||
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void OSystemWinCE::mainLoop()
|
||||
{
|
||||
|
||||
uInt32 frameTime = 0, numberOfFrames = 0;
|
||||
uInt32 startTime, virtualTime, currentTime;
|
||||
|
||||
virtualTime = GetTickCount();
|
||||
frameTime = 0;
|
||||
|
||||
// Main game loop
|
||||
MSG msg;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
while (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
|
||||
{
|
||||
if (msg.message == WM_QUIT)
|
||||
break;
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
if (msg.message == WM_QUIT)
|
||||
break;
|
||||
|
||||
if (myQuitLoop)
|
||||
break;
|
||||
|
||||
if (RequestRefresh)
|
||||
{
|
||||
RequestRefresh = false;
|
||||
myEventHandler->refreshDisplay();
|
||||
}
|
||||
|
||||
startTime = GetTickCount();
|
||||
|
||||
myEventHandler->poll(startTime);
|
||||
myFrameBuffer->update();
|
||||
((SoundWinCE *)mySound)->update();
|
||||
|
||||
currentTime = GetTickCount();
|
||||
virtualTime += myTimePerFrame;
|
||||
if(currentTime < virtualTime)
|
||||
Sleep(virtualTime - currentTime);
|
||||
else
|
||||
virtualTime = currentTime;
|
||||
|
||||
currentTime = GetTickCount() - startTime;
|
||||
frameTime += currentTime;
|
||||
++numberOfFrames;
|
||||
}
|
||||
}
|
||||
|
||||
uInt32 OSystemWinCE::getTicks(void) const
|
||||
{
|
||||
return GetTickCount();
|
||||
}
|
||||
|
||||
void OSystemWinCE::getScreenDimensions(int& width, int& height)
|
||||
{
|
||||
// do not use the framebuffer issmartphonelowres method as the framebuffer has not been created yet
|
||||
if ((unsigned int) GetSystemMetrics(SM_CXSCREEN) != 176 )
|
||||
{
|
||||
if (GetSystemMetrics(SM_CXSCREEN) != GetSystemMetrics(SM_CYSCREEN) )
|
||||
{
|
||||
width = 320;
|
||||
height = 240;
|
||||
}
|
||||
else
|
||||
{
|
||||
width = height = 240;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
width = 220;
|
||||
height = 176;
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// Windows CE Port by Kostas Nakos
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#ifndef OSYSTEM_WINCE_HXX
|
||||
#define OSYSTEM_WINCE_HXX
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "OSystem.hxx"
|
||||
|
||||
class OSystemWinCE : public OSystem
|
||||
{
|
||||
public:
|
||||
OSystemWinCE(const string& path);
|
||||
virtual ~OSystemWinCE();
|
||||
|
||||
public:
|
||||
virtual void mainLoop();
|
||||
virtual uInt32 getTicks(void) const;
|
||||
virtual void setFramerate(uInt32 framerate);
|
||||
virtual void getScreenDimensions(int& width, int& height);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,262 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// Windows CE Port by Kostas Nakos
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#include <queue>
|
||||
#include "FSNode.hxx"
|
||||
#include "EventHandler.hxx"
|
||||
#include "OSystemWinCE.hxx"
|
||||
#include "SettingsWinCE.hxx"
|
||||
#include "PropsSet.hxx"
|
||||
#include "FrameBufferWinCE.hxx"
|
||||
|
||||
extern void KeySetup(void);
|
||||
extern queue <SDL_Event> eventqueue;
|
||||
extern SDLKey RotateKey(SDLKey);
|
||||
|
||||
bool RequestRefresh = false;
|
||||
SDLKey VK_keymap[SDLK_LAST];
|
||||
|
||||
OSystemWinCE* theOSystem = (OSystemWinCE*) NULL;
|
||||
HWND hWnd;
|
||||
bool rotkeystate = 0;
|
||||
|
||||
DWORD REG_bat, REG_ac, REG_disp, bat_timeout;
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
static PAINTSTRUCT ps;
|
||||
SDL_Event e;
|
||||
memset(&e, 0, sizeof(SDL_Event));
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_KEYDOWN:
|
||||
if (wParam == VK_F3)
|
||||
{
|
||||
if (rotkeystate == 0 && theOSystem)
|
||||
if (theOSystem->eventHandler().state() == EventHandler::S_EMULATE)
|
||||
((FrameBufferWinCE *) (&(theOSystem->frameBuffer())))->rotatedisplay();
|
||||
rotkeystate = true;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
rotkeystate = false;
|
||||
e.key.type = SDL_KEYDOWN;
|
||||
e.key.keysym.sym = RotateKey(VK_keymap[wParam]);
|
||||
e.key.keysym.mod = (SDLMod) 0;
|
||||
eventqueue.push(e);
|
||||
return 0;
|
||||
|
||||
case WM_KEYUP:
|
||||
if (wParam == VK_F3 && rotkeystate)
|
||||
{
|
||||
rotkeystate = false;
|
||||
return 0;
|
||||
}
|
||||
e.key.type = SDL_KEYUP;
|
||||
e.key.keysym.sym = RotateKey(VK_keymap[wParam]);
|
||||
e.key.keysym.mod = (SDLMod) 0;
|
||||
eventqueue.push(e);
|
||||
return 0;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
e.type = SDL_MOUSEMOTION;
|
||||
e.motion.x = LOWORD(lParam);
|
||||
e.motion.y = HIWORD(lParam);
|
||||
eventqueue.push(e);
|
||||
return 0;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
e.type = SDL_MOUSEBUTTONDOWN;
|
||||
e.motion.x = LOWORD(lParam);
|
||||
e.motion.y = HIWORD(lParam);
|
||||
e.button.button = SDL_BUTTON_LEFT;
|
||||
eventqueue.push(e);
|
||||
return 0;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
e.type = SDL_MOUSEBUTTONUP;
|
||||
e.motion.x = LOWORD(lParam);
|
||||
e.motion.y = HIWORD(lParam);
|
||||
e.button.button = SDL_BUTTON_LEFT;
|
||||
eventqueue.push(e);
|
||||
return 0;
|
||||
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
|
||||
case WM_CLOSE:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
|
||||
case WM_SETFOCUS:
|
||||
case WM_ACTIVATE:
|
||||
GXResume();
|
||||
if (theOSystem)
|
||||
theOSystem->frameBuffer().refresh();
|
||||
return 0;
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
case WM_HIBERNATE:
|
||||
GXSuspend();
|
||||
if (theOSystem)
|
||||
if (theOSystem->eventHandler().state() == EventHandler::S_EMULATE)
|
||||
theOSystem->eventHandler().enterMenuMode(EventHandler::S_MENU);
|
||||
return 0;
|
||||
|
||||
case WM_PAINT:
|
||||
BeginPaint(hWnd, &ps);
|
||||
EndPaint(hWnd, &ps);
|
||||
RequestRefresh = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
static DWORD reg_access(TCHAR *key, TCHAR *val, DWORD data)
|
||||
{
|
||||
HKEY regkey;
|
||||
DWORD tmpval, cbdata;
|
||||
|
||||
if (RegOpenKeyEx(HKEY_CURRENT_USER, key, 0, 0, ®key) != ERROR_SUCCESS)
|
||||
return data;
|
||||
|
||||
cbdata = sizeof(DWORD);
|
||||
if (RegQueryValueEx(regkey, val, NULL, NULL, (LPBYTE) &tmpval, &cbdata) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(regkey);
|
||||
return data;
|
||||
}
|
||||
|
||||
cbdata = sizeof(DWORD);
|
||||
if (RegSetValueEx(regkey, val, 0, REG_DWORD, (LPBYTE) &data, cbdata) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(regkey);
|
||||
return data;
|
||||
}
|
||||
|
||||
RegCloseKey(regkey);
|
||||
return tmpval;
|
||||
}
|
||||
|
||||
static void backlight_xchg(void)
|
||||
{
|
||||
HANDLE h;
|
||||
|
||||
REG_bat = reg_access(_T("ControlPanel\\BackLight"), _T("BatteryTimeout"), REG_bat);
|
||||
REG_ac = reg_access(_T("ControlPanel\\BackLight"), _T("ACTimeout"), REG_ac);
|
||||
REG_disp = reg_access(_T("ControlPanel\\Power"), _T("Display"), REG_disp);
|
||||
|
||||
h = CreateEvent(NULL, FALSE, FALSE, _T("BackLightChangeEvent"));
|
||||
if (h)
|
||||
{
|
||||
SetEvent(h);
|
||||
CloseHandle(h);
|
||||
}
|
||||
}
|
||||
|
||||
void CleanUp(void)
|
||||
{
|
||||
GXCloseDisplay();
|
||||
GXCloseInput();
|
||||
if(theOSystem) delete theOSystem;
|
||||
backlight_xchg();
|
||||
SystemParametersInfo(SPI_SETBATTERYIDLETIMEOUT, bat_timeout, NULL, SPIF_SENDCHANGE);
|
||||
}
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd )
|
||||
{
|
||||
LPTSTR wndname = _T("PocketStella");
|
||||
WNDCLASS wc = { CS_HREDRAW | CS_VREDRAW, WindowProc, 0, 0, hInstance, NULL, NULL,
|
||||
(HBRUSH)GetStockObject(BLACK_BRUSH), NULL, wndname};
|
||||
RegisterClass(&wc);
|
||||
hWnd = CreateWindow(wndname, wndname, WS_VISIBLE | WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN),
|
||||
GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL);
|
||||
if (!hWnd) return 1;
|
||||
SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
|
||||
|
||||
/* backlight */
|
||||
REG_bat = REG_ac = REG_disp = 2 * 60 * 60 * 1000; /* 2hrs should do it */
|
||||
backlight_xchg();
|
||||
SystemParametersInfo(SPI_GETBATTERYIDLETIMEOUT, 0, (void *) &bat_timeout, 0);
|
||||
SystemParametersInfo(SPI_SETBATTERYIDLETIMEOUT, 60 * 60 * 2, NULL, SPIF_SENDCHANGE);
|
||||
|
||||
// pump the messages to get the window up
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
LOGFONT f = {11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
||||
OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, _T("")};
|
||||
HFONT hFnt = CreateFontIndirect(&f);
|
||||
HDC hDC = GetDC(hWnd);
|
||||
SelectObject(hDC, hFnt);
|
||||
RECT RWnd;
|
||||
GetClipBox(hDC, &RWnd);
|
||||
SetTextColor(hDC, 0xA0A0A0);
|
||||
SetBkColor(hDC, 0);
|
||||
DrawText(hDC, _T("PocketStella Initializing..."), -1, &RWnd, DT_CENTER | DT_VCENTER);
|
||||
ReleaseDC(hWnd, hDC);
|
||||
DeleteObject(hFnt);
|
||||
|
||||
theOSystem = new OSystemWinCE(((string) getcwd()) + '\\');
|
||||
SettingsWinCE theSettings(theOSystem);
|
||||
theOSystem->settings().loadConfig();
|
||||
theOSystem->settings().validate();
|
||||
bool loaddefaultkeys = (theOSystem->settings().getString("keymap") == EmptyString);
|
||||
theOSystem->create();
|
||||
if (loaddefaultkeys)
|
||||
{
|
||||
// setup the default keybindings the first time we're run
|
||||
theOSystem->eventHandler().addKeyMapping(Event::JoystickZeroFire, kEmulationMode, SDLK_F1);
|
||||
theOSystem->eventHandler().addKeyMapping(Event::LauncherMode, kEmulationMode, SDLK_BACKSPACE);
|
||||
theOSystem->eventHandler().addKeyMapping(Event::ConsoleReset, kEmulationMode, SDLK_F6);
|
||||
theOSystem->eventHandler().addKeyMapping(Event::ConsoleSelect, kEmulationMode, SDLK_F5);
|
||||
|
||||
theOSystem->eventHandler().addKeyMapping(Event::UIPgUp, kMenuMode, SDLK_LEFT);
|
||||
theOSystem->eventHandler().addKeyMapping(Event::UIPgDown, kMenuMode, SDLK_RIGHT);
|
||||
theOSystem->eventHandler().addKeyMapping(Event::UISelect, kMenuMode, SDLK_F1);
|
||||
theOSystem->eventHandler().addKeyMapping(Event::UICancel, kMenuMode, SDLK_BACKSPACE);
|
||||
}
|
||||
|
||||
if ( !GXOpenDisplay(hWnd, GX_FULLSCREEN) || !GXOpenInput() )
|
||||
{
|
||||
CleanUp();
|
||||
return 1;
|
||||
}
|
||||
KeySetup();
|
||||
|
||||
string romfile = ((string) getcwd()) + ((string) "\\") + theSettings.getString("GameFilename");
|
||||
if (!FilesystemNode::fileExists(romfile))
|
||||
theOSystem->createLauncher();
|
||||
else
|
||||
theOSystem->createConsole(romfile);
|
||||
|
||||
theOSystem->mainLoop();
|
||||
|
||||
CleanUp();
|
||||
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,37 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// Windows CE Port by Kostas Nakos
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "Settings.hxx"
|
||||
#include "SettingsWinCE.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
SettingsWinCE::SettingsWinCE(OSystem* osystem) : Settings(osystem)
|
||||
{
|
||||
setInternal("romdir", (string) getcwd() + "\\Roms\\");
|
||||
setInternal("wince_orientation", "0");
|
||||
}
|
||||
|
||||
SettingsWinCE::~SettingsWinCE()
|
||||
{
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// Windows CE Port by Kostas Nakos
|
||||
//============================================================================
|
||||
|
||||
#ifndef SETTINGS_WINCE_HXX
|
||||
#define SETTINGS_WINCE_HXX
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "Settings.hxx"
|
||||
|
||||
class SettingsWinCE : public Settings
|
||||
{
|
||||
public:
|
||||
SettingsWinCE(OSystem* osystem);
|
||||
virtual ~SettingsWinCE();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,413 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// Windows CE Port by Kostas Nakos
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#ifdef SOUND_SUPPORT
|
||||
|
||||
#include "TIASnd.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "Settings.hxx"
|
||||
#include "System.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "TIASnd.hxx"
|
||||
|
||||
#include "SoundWinCE.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
SoundWinCE::SoundWinCE(OSystem* osystem)
|
||||
: Sound(osystem),
|
||||
myIsEnabled(osystem->settings().getBool("sound")),
|
||||
myIsInitializedFlag(false),
|
||||
myLastRegisterSetCycle(0),
|
||||
myDisplayFrameRate(60),
|
||||
myNumChannels(1),
|
||||
myFragmentSizeLogBase2(0),
|
||||
myIsMuted(false),
|
||||
myVolume(100),
|
||||
myLatency(100), myMixRate(22050), myBuffnum(0)
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
SoundWinCE::~SoundWinCE()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SoundWinCE::setEnabled(bool state)
|
||||
{
|
||||
myIsEnabled = state;
|
||||
myOSystem->settings().setBool("sound", state);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SoundWinCE::initialize()
|
||||
{
|
||||
int i;
|
||||
|
||||
if(!myIsEnabled)
|
||||
{
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
myRegWriteQueue.clear();
|
||||
myTIASound.reset();
|
||||
|
||||
// init wave out
|
||||
WAVEFORMATEX wf;
|
||||
MMRESULT err;
|
||||
memset(&wf, 0, sizeof(wf));
|
||||
wf.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wf.nChannels = 1;
|
||||
wf.nSamplesPerSec = myMixRate;
|
||||
wf.nAvgBytesPerSec = myMixRate;
|
||||
wf.nBlockAlign = 2;
|
||||
wf.wBitsPerSample = 8;
|
||||
wf.cbSize = 0;
|
||||
err = waveOutOpen(&myWout, WAVE_MAPPER, &wf, NULL, NULL, CALLBACK_NULL);
|
||||
if (err != MMSYSERR_NOERROR)
|
||||
return;
|
||||
|
||||
myBuffnum = ((wf.nAvgBytesPerSec * myLatency / 1000) >> 9) + 1;
|
||||
myBuffers = (WAVEHDR *) malloc(myBuffnum * sizeof(*myBuffers));
|
||||
for (i = 0; i < myBuffnum; i++)
|
||||
{
|
||||
memset(&myBuffers[i], 0, sizeof (myBuffers[i]));
|
||||
if (!(myBuffers[i].lpData = (LPSTR) malloc(512)))
|
||||
return;
|
||||
memset(myBuffers[i].lpData, 128, 512);
|
||||
myBuffers[i].dwBufferLength = 512;
|
||||
err = waveOutPrepareHeader(myWout, &myBuffers[i], sizeof(myBuffers[i]));
|
||||
if (err != MMSYSERR_NOERROR)
|
||||
return;
|
||||
myBuffers[i].dwFlags |= WHDR_DONE;
|
||||
}
|
||||
|
||||
myIsInitializedFlag = true;
|
||||
myIsMuted = false;
|
||||
|
||||
myTIASound.outputFrequency(myMixRate);
|
||||
myTIASound.channels(1);
|
||||
|
||||
for (i=0; i<myBuffnum; i++)
|
||||
waveOutWrite(myWout, &myBuffers[i], sizeof(WAVEHDR));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SoundWinCE::close()
|
||||
{
|
||||
if(myIsInitializedFlag)
|
||||
{
|
||||
int flag;
|
||||
do
|
||||
{
|
||||
flag = true;
|
||||
for (int i=0; i<myBuffnum; i++)
|
||||
{
|
||||
if (!(myBuffers[i].dwFlags & WHDR_DONE))
|
||||
{
|
||||
flag = false;
|
||||
Sleep(myLatency);
|
||||
}
|
||||
}
|
||||
} while (flag = false);
|
||||
|
||||
waveOutReset(myWout);
|
||||
|
||||
for (int i=0; i<myBuffnum; i++)
|
||||
{
|
||||
if (waveOutUnprepareHeader(myWout, &myBuffers[i], sizeof(WAVEHDR)) != MMSYSERR_NOERROR)
|
||||
return;
|
||||
free(myBuffers[i].lpData);
|
||||
}
|
||||
free(myBuffers);
|
||||
waveOutClose(myWout);
|
||||
|
||||
myIsInitializedFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool SoundWinCE::isSuccessfullyInitialized() const
|
||||
{
|
||||
return myIsInitializedFlag;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SoundWinCE::mute(bool state)
|
||||
{
|
||||
if(myIsInitializedFlag)
|
||||
{
|
||||
if(myIsMuted == state)
|
||||
return;
|
||||
myIsMuted = state;
|
||||
myRegWriteQueue.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SoundWinCE::reset()
|
||||
{
|
||||
if(myIsInitializedFlag)
|
||||
{
|
||||
myIsMuted = false;
|
||||
myLastRegisterSetCycle = 0;
|
||||
myRegWriteQueue.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SoundWinCE::setVolume(Int32 percent)
|
||||
{
|
||||
if(myIsInitializedFlag)
|
||||
{
|
||||
if((percent >= 0) && (percent <= 100))
|
||||
{
|
||||
myOSystem->settings().setInt("volume", percent);
|
||||
myVolume = percent;
|
||||
myTIASound.volume(percent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SoundWinCE::adjustVolume(Int8 direction)
|
||||
{
|
||||
Int32 percent = myVolume;
|
||||
|
||||
if(direction == -1)
|
||||
percent -= 2;
|
||||
else if(direction == 1)
|
||||
percent += 2;
|
||||
|
||||
if((percent < 0) || (percent > 100))
|
||||
return;
|
||||
|
||||
setVolume(percent);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SoundWinCE::adjustCycleCounter(Int32 amount)
|
||||
{
|
||||
myLastRegisterSetCycle += amount;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SoundWinCE::setChannels(uInt32 channels)
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SoundWinCE::setFrameRate(uInt32 framerate)
|
||||
{
|
||||
myDisplayFrameRate = framerate;
|
||||
myLastRegisterSetCycle = 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SoundWinCE::set(uInt16 addr, uInt8 value, Int32 cycle)
|
||||
{
|
||||
float delta = (((double)(cycle - myLastRegisterSetCycle)) / (1193191.66666667));
|
||||
delta = delta * (myDisplayFrameRate / (double)myOSystem->frameRate());
|
||||
RegWrite info;
|
||||
info.addr = addr;
|
||||
info.value = value;
|
||||
info.delta = delta;
|
||||
myRegWriteQueue.enqueue(info);
|
||||
myLastRegisterSetCycle = cycle;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SoundWinCE::processFragment(uInt8* stream, Int32 length)
|
||||
{
|
||||
if(!myIsInitializedFlag)
|
||||
return;
|
||||
|
||||
float position = 0.0;
|
||||
float remaining = length;
|
||||
|
||||
if(myRegWriteQueue.duration() >
|
||||
(9.0 / myDisplayFrameRate))
|
||||
{
|
||||
float removed = 0.0;
|
||||
while(removed < ((9.0 - 1) / myDisplayFrameRate))
|
||||
{
|
||||
RegWrite& info = myRegWriteQueue.front();
|
||||
removed += info.delta;
|
||||
myTIASound.set(info.addr, info.value);
|
||||
myRegWriteQueue.dequeue();
|
||||
}
|
||||
// cout << "Removed Items from RegWriteQueue!" << endl;
|
||||
}
|
||||
|
||||
while(remaining > 0.0)
|
||||
{
|
||||
if(myRegWriteQueue.size() == 0)
|
||||
{
|
||||
myTIASound.process(stream + ((uInt32)position),length - (uInt32)position);
|
||||
myLastRegisterSetCycle = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
RegWrite& info = myRegWriteQueue.front();
|
||||
float duration = remaining / (float) myMixRate;
|
||||
if(info.delta <= duration)
|
||||
{
|
||||
if(info.delta > 0.0)
|
||||
{
|
||||
float samples = (myMixRate * info.delta);
|
||||
myTIASound.process(stream + ((uInt32)position),
|
||||
(uInt32)samples + (uInt32)(position + samples) -
|
||||
((uInt32)position + (uInt32)samples));
|
||||
position += samples;
|
||||
remaining -= samples;
|
||||
}
|
||||
myTIASound.set(info.addr, info.value);
|
||||
myRegWriteQueue.dequeue();
|
||||
}
|
||||
else
|
||||
{
|
||||
myTIASound.process(stream + ((uInt32)position), length - (uInt32)position);
|
||||
info.delta -= duration;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
/*void CALLBACK SoundWinCE::waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance,
|
||||
DWORD dwParam1, DWORD dwParam2)
|
||||
{
|
||||
if (uMsg == WOM_DONE)
|
||||
{
|
||||
SoundWinCE *sound = (SoundWinCE *) dwInstance;
|
||||
sound->processFragment( (uInt8 *) ((WAVEHDR *) dwParam2)->lpData, 512);
|
||||
waveOutWrite(sound->myWout, (WAVEHDR *) dwParam2, sizeof(WAVEHDR));
|
||||
}
|
||||
}
|
||||
*/
|
||||
void SoundWinCE::update(void)
|
||||
{
|
||||
if (myIsMuted) return;
|
||||
for (int i=0; i<myBuffnum; i++)
|
||||
if (myBuffers[i].dwFlags & WHDR_DONE)
|
||||
{
|
||||
processFragment((uInt8 *) myBuffers[i].lpData, 512);
|
||||
waveOutWrite(myWout, &myBuffers[i], sizeof(WAVEHDR));
|
||||
}
|
||||
}
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool SoundWinCE::load(Serializer& in)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool SoundWinCE::save(Serializer& out)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
SoundWinCE::RegWriteQueue::RegWriteQueue(uInt32 capacity)
|
||||
: myCapacity(capacity),
|
||||
myBuffer(0),
|
||||
mySize(0),
|
||||
myHead(0),
|
||||
myTail(0)
|
||||
{
|
||||
myBuffer = new RegWrite[myCapacity];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
SoundWinCE::RegWriteQueue::~RegWriteQueue()
|
||||
{
|
||||
delete[] myBuffer;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SoundWinCE::RegWriteQueue::clear()
|
||||
{
|
||||
myHead = myTail = mySize = 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SoundWinCE::RegWriteQueue::dequeue()
|
||||
{
|
||||
if(mySize > 0)
|
||||
{
|
||||
myHead = (myHead + 1) % myCapacity;
|
||||
--mySize;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
float SoundWinCE::RegWriteQueue::duration()
|
||||
{
|
||||
float duration = 0.0;
|
||||
for(uInt32 i = 0; i < mySize; ++i)
|
||||
{
|
||||
duration += myBuffer[(myHead + i) % myCapacity].delta;
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SoundWinCE::RegWriteQueue::enqueue(const RegWrite& info)
|
||||
{
|
||||
if(mySize == myCapacity)
|
||||
grow();
|
||||
myBuffer[myTail] = info;
|
||||
myTail = (myTail + 1) % myCapacity;
|
||||
++mySize;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
RegWrite& SoundWinCE::RegWriteQueue::front()
|
||||
{
|
||||
assert(mySize != 0);
|
||||
return myBuffer[myHead];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 SoundWinCE::RegWriteQueue::size() const
|
||||
{
|
||||
return mySize;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SoundWinCE::RegWriteQueue::grow()
|
||||
{
|
||||
RegWrite* buffer = new RegWrite[myCapacity * 2];
|
||||
for(uInt32 i = 0; i < mySize; ++i)
|
||||
{
|
||||
buffer[i] = myBuffer[(myHead + i) % myCapacity];
|
||||
}
|
||||
myHead = 0;
|
||||
myTail = mySize;
|
||||
myCapacity = myCapacity * 2;
|
||||
delete[] myBuffer;
|
||||
myBuffer = buffer;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,105 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// Windows CE Port by Kostas Nakos
|
||||
//============================================================================
|
||||
|
||||
#ifndef SOUNDWINCE_HXX
|
||||
#define SOUNDWINCE_HXX
|
||||
|
||||
#ifdef SOUND_SUPPORT
|
||||
|
||||
class OSystem;
|
||||
|
||||
#include "Sound.hxx"
|
||||
#include "bspf.hxx"
|
||||
#include "MediaSrc.hxx"
|
||||
#include "TIASnd.hxx"
|
||||
|
||||
struct RegWrite
|
||||
{
|
||||
uInt16 addr;
|
||||
uInt8 value;
|
||||
double delta;
|
||||
};
|
||||
|
||||
|
||||
class SoundWinCE : public Sound
|
||||
{
|
||||
public:
|
||||
SoundWinCE(OSystem* osystem);
|
||||
virtual ~SoundWinCE();
|
||||
void setEnabled(bool state);
|
||||
void adjustCycleCounter(Int32 amount);
|
||||
void setChannels(uInt32 channels);
|
||||
void setFrameRate(uInt32 framerate);
|
||||
void initialize();
|
||||
void close();
|
||||
bool isSuccessfullyInitialized() const;
|
||||
void mute(bool state);
|
||||
void reset();
|
||||
void set(uInt16 addr, uInt8 value, Int32 cycle);
|
||||
void setVolume(Int32 percent);
|
||||
void adjustVolume(Int8 direction);
|
||||
bool load(Serializer& in);
|
||||
bool save(Serializer& out);
|
||||
void update(void);
|
||||
|
||||
protected:
|
||||
void processFragment(uInt8* stream, Int32 length);
|
||||
// Struct to hold information regarding a TIA sound register write
|
||||
class RegWriteQueue
|
||||
{
|
||||
public:
|
||||
RegWriteQueue(uInt32 capacity = 512);
|
||||
virtual ~RegWriteQueue();
|
||||
void clear();
|
||||
void dequeue();
|
||||
float duration();
|
||||
void enqueue(const RegWrite& info);
|
||||
RegWrite& front();
|
||||
uInt32 size() const;
|
||||
|
||||
private:
|
||||
void grow();
|
||||
|
||||
private:
|
||||
uInt32 myCapacity;
|
||||
RegWrite* myBuffer;
|
||||
uInt32 mySize;
|
||||
uInt32 myHead;
|
||||
uInt32 myTail;
|
||||
};
|
||||
|
||||
private:
|
||||
TIASound myTIASound;
|
||||
bool myIsEnabled;
|
||||
bool myIsInitializedFlag;
|
||||
Int32 myLastRegisterSetCycle;
|
||||
uInt32 myDisplayFrameRate;
|
||||
uInt32 myNumChannels;
|
||||
double myFragmentSizeLogBase2;
|
||||
bool myIsMuted;
|
||||
uInt32 myVolume;
|
||||
RegWriteQueue myRegWriteQueue;
|
||||
//static void CALLBACK SoundWinCE::waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
|
||||
int myLatency, myMixRate, myBuffnum;
|
||||
WAVEHDR *myBuffers;
|
||||
HWAVEOUT myWout;
|
||||
};
|
||||
|
||||
#endif // SOUND_SUPPORT
|
||||
#endif
|
|
@ -1,301 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// Windows CE Port by Kostas Nakos
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#include <queue>
|
||||
#include "bspf.hxx"
|
||||
#include "SDL.h"
|
||||
#include "OSystemWinCE.hxx"
|
||||
#include "FrameBufferWinCE.hxx"
|
||||
#include "EventHandler.hxx"
|
||||
|
||||
char *msg = NULL;
|
||||
extern OSystemWinCE *theOSystem;
|
||||
extern SDLKey VK_keymap[SDLK_LAST];
|
||||
|
||||
queue <SDL_Event> eventqueue;
|
||||
|
||||
int time(int dummy)
|
||||
{
|
||||
return GetTickCount();
|
||||
}
|
||||
|
||||
char *getcwd(void)
|
||||
{
|
||||
TCHAR fileUnc[MAX_PATH+1];
|
||||
static char cwd[MAX_PATH+1] = "";
|
||||
char *plast;
|
||||
|
||||
GetModuleFileName(NULL, fileUnc, MAX_PATH);
|
||||
WideCharToMultiByte(CP_ACP, 0, fileUnc, -1, cwd, MAX_PATH, NULL, NULL);
|
||||
plast = strrchr(cwd, '\\');
|
||||
if(plast)
|
||||
*plast = 0;
|
||||
|
||||
return cwd;
|
||||
}
|
||||
|
||||
SDLKey RotateKey(SDLKey key)
|
||||
{
|
||||
uInt8 dir = 0;
|
||||
uInt8 mode = ((FrameBufferWinCE *) (&(theOSystem->frameBuffer())))->getmode();
|
||||
uInt8 state = theOSystem->eventHandler().state();
|
||||
bool lscp = ((FrameBufferWinCE *) (&(theOSystem->frameBuffer())))->IsLandscape();
|
||||
|
||||
if (!(lscp && mode == 0))
|
||||
if (state != EventHandler::S_EMULATE)
|
||||
if (mode != 2)
|
||||
dir = 1;
|
||||
else
|
||||
dir = 2;
|
||||
else
|
||||
dir = mode;
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case 0:
|
||||
return key;
|
||||
|
||||
case 1:
|
||||
switch (key)
|
||||
{
|
||||
case SDLK_LEFT:
|
||||
return SDLK_UP;
|
||||
case SDLK_DOWN:
|
||||
return SDLK_LEFT;
|
||||
case SDLK_RIGHT:
|
||||
return SDLK_DOWN;
|
||||
case SDLK_UP:
|
||||
return SDLK_RIGHT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
switch (key)
|
||||
{
|
||||
case SDLK_LEFT:
|
||||
return SDLK_DOWN;
|
||||
case SDLK_DOWN:
|
||||
return SDLK_RIGHT;
|
||||
case SDLK_RIGHT:
|
||||
return SDLK_UP;
|
||||
case SDLK_UP:
|
||||
return SDLK_LEFT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
void KeySetup(void)
|
||||
{
|
||||
// Map the VK keysyms
|
||||
// stolen from SDL_dibevents.c :-)
|
||||
for (int i=0; i<SDLK_LAST; ++i )
|
||||
VK_keymap[i] = SDLK_UNKNOWN;
|
||||
|
||||
VK_keymap[VK_BACK] = SDLK_BACKSPACE;
|
||||
VK_keymap[VK_TAB] = SDLK_TAB;
|
||||
VK_keymap[VK_CLEAR] = SDLK_CLEAR;
|
||||
VK_keymap[VK_RETURN] = SDLK_RETURN;
|
||||
VK_keymap[VK_PAUSE] = SDLK_PAUSE;
|
||||
VK_keymap[VK_ESCAPE] = SDLK_ESCAPE;
|
||||
VK_keymap[VK_SPACE] = SDLK_SPACE;
|
||||
VK_keymap[VK_APOSTROPHE] = SDLK_QUOTE;
|
||||
VK_keymap[VK_COMMA] = SDLK_COMMA;
|
||||
VK_keymap[VK_PERIOD] = SDLK_PERIOD;
|
||||
VK_keymap[VK_SLASH] = SDLK_SLASH;
|
||||
VK_keymap['0'] = SDLK_0;
|
||||
VK_keymap['1'] = SDLK_1;
|
||||
VK_keymap['2'] = SDLK_2;
|
||||
VK_keymap['3'] = SDLK_3;
|
||||
VK_keymap['4'] = SDLK_4;
|
||||
VK_keymap['5'] = SDLK_5;
|
||||
VK_keymap['6'] = SDLK_6;
|
||||
VK_keymap['7'] = SDLK_7;
|
||||
VK_keymap['8'] = SDLK_8;
|
||||
VK_keymap['9'] = SDLK_9;
|
||||
VK_keymap[VK_SEMICOLON] = SDLK_SEMICOLON;
|
||||
VK_keymap[VK_EQUAL] = SDLK_EQUALS;
|
||||
VK_keymap[VK_LBRACKET] = SDLK_LEFTBRACKET;
|
||||
VK_keymap[VK_BACKSLASH] = SDLK_BACKSLASH;
|
||||
VK_keymap[VK_RBRACKET] = SDLK_RIGHTBRACKET;
|
||||
VK_keymap[VK_BACKQUOTE] = SDLK_BACKQUOTE;
|
||||
VK_keymap['A'] = SDLK_a;
|
||||
VK_keymap['B'] = SDLK_b;
|
||||
VK_keymap['C'] = SDLK_c;
|
||||
VK_keymap['D'] = SDLK_d;
|
||||
VK_keymap['E'] = SDLK_e;
|
||||
VK_keymap['F'] = SDLK_f;
|
||||
VK_keymap['G'] = SDLK_g;
|
||||
VK_keymap['H'] = SDLK_h;
|
||||
VK_keymap['I'] = SDLK_i;
|
||||
VK_keymap['J'] = SDLK_j;
|
||||
VK_keymap['K'] = SDLK_k;
|
||||
VK_keymap['L'] = SDLK_l;
|
||||
VK_keymap['M'] = SDLK_m;
|
||||
VK_keymap['N'] = SDLK_n;
|
||||
VK_keymap['O'] = SDLK_o;
|
||||
VK_keymap['P'] = SDLK_p;
|
||||
VK_keymap['Q'] = SDLK_q;
|
||||
VK_keymap['R'] = SDLK_r;
|
||||
VK_keymap['S'] = SDLK_s;
|
||||
VK_keymap['T'] = SDLK_t;
|
||||
VK_keymap['U'] = SDLK_u;
|
||||
VK_keymap['V'] = SDLK_v;
|
||||
VK_keymap['W'] = SDLK_w;
|
||||
VK_keymap['X'] = SDLK_x;
|
||||
VK_keymap['Y'] = SDLK_y;
|
||||
VK_keymap['Z'] = SDLK_z;
|
||||
VK_keymap[VK_DELETE] = SDLK_DELETE;
|
||||
|
||||
VK_keymap[VK_NUMPAD0] = SDLK_KP0;
|
||||
VK_keymap[VK_NUMPAD1] = SDLK_KP1;
|
||||
VK_keymap[VK_NUMPAD2] = SDLK_KP2;
|
||||
VK_keymap[VK_NUMPAD3] = SDLK_KP3;
|
||||
VK_keymap[VK_NUMPAD4] = SDLK_KP4;
|
||||
VK_keymap[VK_NUMPAD5] = SDLK_KP5;
|
||||
VK_keymap[VK_NUMPAD6] = SDLK_KP6;
|
||||
VK_keymap[VK_NUMPAD7] = SDLK_KP7;
|
||||
VK_keymap[VK_NUMPAD8] = SDLK_KP8;
|
||||
VK_keymap[VK_NUMPAD9] = SDLK_KP9;
|
||||
VK_keymap[VK_DECIMAL] = SDLK_KP_PERIOD;
|
||||
VK_keymap[VK_DIVIDE] = SDLK_KP_DIVIDE;
|
||||
VK_keymap[VK_MULTIPLY] = SDLK_KP_MULTIPLY;
|
||||
VK_keymap[VK_SUBTRACT] = SDLK_KP_MINUS;
|
||||
VK_keymap[VK_ADD] = SDLK_KP_PLUS;
|
||||
|
||||
VK_keymap[VK_UP] = SDLK_UP;
|
||||
VK_keymap[VK_DOWN] = SDLK_DOWN;
|
||||
VK_keymap[VK_RIGHT] = SDLK_RIGHT;
|
||||
VK_keymap[VK_LEFT] = SDLK_LEFT;
|
||||
VK_keymap[VK_INSERT] = SDLK_INSERT;
|
||||
VK_keymap[VK_HOME] = SDLK_HOME;
|
||||
VK_keymap[VK_END] = SDLK_END;
|
||||
VK_keymap[VK_PRIOR] = SDLK_PAGEUP;
|
||||
VK_keymap[VK_NEXT] = SDLK_PAGEDOWN;
|
||||
|
||||
VK_keymap[VK_F1] = SDLK_F1;
|
||||
VK_keymap[VK_F2] = SDLK_F2;
|
||||
VK_keymap[VK_F3] = SDLK_F3;
|
||||
VK_keymap[VK_F4] = SDLK_F4;
|
||||
VK_keymap[VK_F5] = SDLK_F5;
|
||||
VK_keymap[VK_F6] = SDLK_F6;
|
||||
VK_keymap[VK_F7] = SDLK_F7;
|
||||
VK_keymap[VK_F8] = SDLK_F8;
|
||||
VK_keymap[VK_F9] = SDLK_F9;
|
||||
VK_keymap[VK_F10] = SDLK_F10;
|
||||
VK_keymap[VK_F11] = SDLK_F11;
|
||||
VK_keymap[VK_F12] = SDLK_F12;
|
||||
VK_keymap[VK_F13] = SDLK_F13;
|
||||
VK_keymap[VK_F14] = SDLK_F14;
|
||||
VK_keymap[VK_F15] = SDLK_F15;
|
||||
|
||||
VK_keymap[VK_NUMLOCK] = SDLK_NUMLOCK;
|
||||
VK_keymap[VK_CAPITAL] = SDLK_CAPSLOCK;
|
||||
VK_keymap[VK_SCROLL] = SDLK_SCROLLOCK;
|
||||
VK_keymap[VK_RSHIFT] = SDLK_RSHIFT;
|
||||
VK_keymap[VK_LSHIFT] = SDLK_LSHIFT;
|
||||
VK_keymap[VK_RCONTROL] = SDLK_RCTRL;
|
||||
VK_keymap[VK_LCONTROL] = SDLK_LCTRL;
|
||||
VK_keymap[VK_RMENU] = SDLK_RALT;
|
||||
VK_keymap[VK_LMENU] = SDLK_LALT;
|
||||
VK_keymap[VK_RWIN] = SDLK_RSUPER;
|
||||
VK_keymap[VK_LWIN] = SDLK_LSUPER;
|
||||
|
||||
VK_keymap[VK_HELP] = SDLK_HELP;
|
||||
VK_keymap[VK_PRINT] = SDLK_PRINT;
|
||||
VK_keymap[VK_SNAPSHOT] = SDLK_PRINT;
|
||||
VK_keymap[VK_CANCEL] = SDLK_BREAK;
|
||||
VK_keymap[VK_APPS] = SDLK_MENU;
|
||||
|
||||
// fix wince keys
|
||||
GXKeyList klist = GXGetDefaultKeys(GX_NORMALKEYS);
|
||||
|
||||
VK_keymap[klist.vkUp] = SDLK_UP;
|
||||
VK_keymap[klist.vkDown] = SDLK_DOWN;
|
||||
VK_keymap[klist.vkLeft] = SDLK_LEFT;
|
||||
VK_keymap[klist.vkRight] = SDLK_RIGHT;
|
||||
VK_keymap[klist.vkA] = SDLK_F1;
|
||||
VK_keymap[klist.vkB] = SDLK_TAB; // harwire softkey2 to tab
|
||||
// VK_F3 => SDLK_F3 is call button, VK_F4 => SDLK_F4 is end call button
|
||||
VK_keymap[klist.vkC] = SDLK_F5;
|
||||
VK_keymap[klist.vkStart] = SDLK_F6;
|
||||
}
|
||||
|
||||
// SDL
|
||||
DECLSPEC Uint32 SDLCALL SDL_WasInit(Uint32 flags) { return 0xFFFFFFFF; }
|
||||
DECLSPEC int SDLCALL SDL_EnableUNICODE(int enable) { return 1; }
|
||||
DECLSPEC int SDLCALL SDL_Init(Uint32 flags) { return 1; }
|
||||
DECLSPEC int SDLCALL SDL_ShowCursor(int toggle) { return 1; }
|
||||
DECLSPEC SDL_GrabMode SDLCALL SDL_WM_GrabInput(SDL_GrabMode mode) { return SDL_GRAB_ON; }
|
||||
DECLSPEC void SDLCALL SDL_WM_SetCaption(const char *title, const char *icon) { return; }
|
||||
DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface *surface) { return; }
|
||||
DECLSPEC void SDLCALL SDL_WM_SetIcon(SDL_Surface *icon, Uint8 *mask) { return; }
|
||||
DECLSPEC SDL_Surface * SDLCALL SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) { return NULL; }
|
||||
DECLSPEC void SDLCALL SDL_WarpMouse(Uint16 x, Uint16 y) { return; }
|
||||
DECLSPEC void SDL_Delay(Uint32 ms) { Sleep(ms); }
|
||||
|
||||
|
||||
DECLSPEC int SDLCALL SDL_PollEvent(SDL_Event *event)
|
||||
{
|
||||
static bool cornertap[4] = {false, false, false, false};
|
||||
|
||||
while (!eventqueue.empty())
|
||||
{
|
||||
memcpy(event, &(eventqueue.front()), sizeof(SDL_Event));
|
||||
eventqueue.pop();
|
||||
|
||||
// tap in corners
|
||||
if ((event->type == SDL_MOUSEBUTTONDOWN || event->type == SDL_MOUSEBUTTONUP) && theOSystem->eventHandler().state() == EventHandler::S_EMULATE)
|
||||
if (event->type == SDL_MOUSEBUTTONDOWN)
|
||||
{
|
||||
uInt16 cs = ((FrameBufferWinCE *) (&(theOSystem->frameBuffer())))->IsVGA() ? 40 : 20;
|
||||
uInt16 x = event->motion.x;
|
||||
uInt16 y = event->motion.y;
|
||||
uInt16 sx, sy;
|
||||
((FrameBufferWinCE *) (&(theOSystem->frameBuffer())))->GetScreenExtents(&sx, &sy);
|
||||
if (x > (sx - cs) && y > (sy - cs) && !cornertap[0])
|
||||
{ // bottom right corner for rotate
|
||||
((FrameBufferWinCE *) (&(theOSystem->frameBuffer())))->rotatedisplay();
|
||||
cornertap[0] = true;
|
||||
continue;
|
||||
}
|
||||
else if (x < cs && y > (sy - cs) && !cornertap[1])
|
||||
{ // bottom left corner for launcher
|
||||
theOSystem->eventHandler().handleEvent(Event::LauncherMode, EventHandler::S_EMULATE);
|
||||
cornertap[1] = true;
|
||||
}
|
||||
else if (x < cs && y < cs && !cornertap[2])
|
||||
{ // top left for menu
|
||||
theOSystem->eventHandler().enterMenuMode(EventHandler::S_MENU);
|
||||
cornertap[2] = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cornertap[0] = cornertap[1] = cornertap[2] = false;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
event->type = SDL_NOEVENT;
|
||||
return 0;
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// Windows CE Port by Kostas Nakos
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#ifndef _WCE_MISSING_H_
|
||||
#define _WCE_MISSING_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// WCE 300 does not support exception handling well
|
||||
// so we remove all catch blocks
|
||||
#define try if (1)
|
||||
#define catch(a) else if (0)
|
||||
extern char *msg;
|
||||
#define throw //
|
||||
|
||||
#define stricmp _stricmp
|
||||
#define strdup _strdup
|
||||
|
||||
#pragma warning(disable: 4800)
|
||||
#pragma warning(disable: 4244)
|
||||
#pragma warning(disable: 4786)
|
||||
|
||||
typedef unsigned int uintptr_t;
|
||||
|
||||
int time(int dummy);
|
||||
char *getcwd(void);
|
||||
|
||||
#endif
|
|
@ -1,16 +0,0 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by resource.rc
|
||||
//
|
||||
#define IDI_STELLA 101
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
|
@ -1,73 +0,0 @@
|
|||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
/*
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
*/
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""resource.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_STELLA ICON DISCARDABLE "stella.ico"
|
||||
HI_RES_AWARE CEUX {1}
|
||||
//#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB |
Loading…
Reference in New Issue