Compare commits

...
2 Commits
Author SHA1 Message Date
byuu a1980fab09 Update to bsnes v021 release.
This is a maintainence release. I am mostly releasing this for the sake of the recently released Der Langrisser translation.
Changelog:
Windows port can once again map joypads through the Input Configuration panel
Using enter or spacebar to assign a key should no longer instantly map those keys
F11 now toggles fullscreen mode
Esc now toggles menu on and off (use F11+Esc combined to hide UI completely)
Fixed a bug in King of Dragons (J, U, E), KOFF was not cleared during S-DSP power(), thanks to FitzRoy for the report, and blargg for assistance fixing the bug
Fixed serious crashing error with File->Load on Linux/amd64 port
Hopefully fixed min/max undefined error on GCC 4.2.0, but I am unable to test to verify
Fixed many cast const char* to char* warnings for GCC 4.2.0, but some probably remain, as again, I am unable to test as I lack GCC 4.2.0
Set XV_AUTO_COLORKEY to 1 for Video/Xv renderer. Should fix some video drivers where there was no output, especially after running mplayer, etc. Thanks to sinimas for the fix
Added clear_video() to Video/Xv renderer. Green edges at the bottom and right sides of the video output are now gone, and unloading a ROM will clear video
I have finally figured out how to poll the keyboard status in real-time through Xorg: the XQueryKeymap function. I will be rewriting the Linux key capture system to use this, instead of capturing window key up / down messages through GTK+. This will finally allow me to completely abstract the UI from the hardware video, audio and input interfaces: a necessary step toward Linux joypad support.
2007-06-10 19:27:46 +00:00
byuu ebb234ba5f Update to bsnes v020 01 release.
[No changelog available]
2007-06-05 15:50:59 +00:00
50 changed files with 828 additions and 1358 deletions

No files matched your search

BIN
View File
Binary file not shown.
+63
View File
@@ -0,0 +1,63 @@
bsnes (TM) Open Source Reference License
Copyright (C) 2004 - 2007 byuu
All rights reserved
1. Definitions
The terms "reproduce", "reproduction", "distribute" and "distribution" have the
same meaning here as under U.S. copyright law.
"The software" means this software package as a whole, including, but not
limited to, this license, binaries, source code, documentation, and data.
"You" means the licensee of the software.
"The licensor" means the copyright holder of the software, byuu.
2. Grant of Rights
Subject to the terms of this license, the licensor grants you a
non-transferable, non-exclusive, worldwide, royalty-free copyright license to
reproduce the software for non-commercial use only, provided the software
remains unmodified, and there is no charge for the software itself, its' use,
nor for the medium upon which the software is distributed. The reproduction of
modified or derivative works of the software is strictly prohibited, except when
transmitted solely to the licensor.
3. Limitations
This license does not grant you any rights to use the licensor's name, logo or
trademarks.
The software is provided "as is", and any express or implied warranties,
including, but not limited to, the implied warranties of merchantability and
fitness for a particular purpose are disclaimed. In no event shall the licensor
be liable for any direct, indirect, incidental, special, exemplary, or
consequential damages (including, but not limited to, procurement of substitute
goods or services; loss of use, data, or profits; or business interruption)
however caused and on any theory of liability, whether in contract, strict
liability, or tort (including negligence or otherwise) arising in any way out of
the use of the software, even if advised of the possibility of such damage.
In the event that this license is determined to be invalid or unenforceable, the
Grant of Rights will become null and void, and no rights shall be granted to the
licensee, within the scope of U.S. copyright law.
4. Exemptions
The software includes the work of other copyright holders, which is licensed
under different agreements, and exempt from this license. Below is a complete
list of all such software, and their respective copyright holders and licenses.
Further, respective source code files are labeled with their correct licensing
information in the header. The lack of such a header indicates said file falls
under the bsnes license.
HQ2x Filter, author: MaxST, license: LGPL
JMA, author: NSRT Team, license: GPL *
libco, author: byuu, license: public domain
libui, author: byuu, license: public domain
NTSC Filter, author: blargg, license: LGPL
S-DD1, author: Andreas Naive, license: public domain
zlib, license: zlib license
* bsnes has received an exemption from the copyright holder to use this work.
+88
View File
@@ -0,0 +1,88 @@
bsnes
Version 0.021
Author: byuu
General:
--------
bsnes is a Super Nintendo / Super Famicom emulator that began on
October 14th, 2004.
The latest version can be downloaded from:
http://byuu.org/
Please see license.txt for important licensing information.
Known Limitations:
------------------
S-CPU
- Invalid DMA / HDMA transfers (eg WRAM<>WRAM) not fully emulated
- Multiply / Divide register delays not implemented
S-PPU
- Uses scanline-based renderer. This is very inaccurate, but very few games
rely on mid-scanline writes to function correctly
- Does not support FirstSprite+Y priority
- OAM / CGRAM accesses during active display not supported correctly
- RTO flags are not calculated on frames that are skipped when frameskipping
is enabled. This provides a major speedup, however it will cause in issues
in games that test these flags, eg the SNES Test Program Electronics Test.
Turning frameskipping off will allow RTO flag calculation on every frame
Hardware Bugs
- CPUr1 HDMA crashing bug not emulated
- CPU<>APU communication bus conflicts not emulated
Unsupported Hardware:
---------------------
SA-1
Coprocessor used in many popular games, including:
- Dragon Ball Z Hyper Dimension
- Kirby Super Star
- Kirby's Dreamland 3
- Marvelous
- SD Gundam G-NEXT
- Super Mario RPG
Super FX
Coprocessor used in many popular games, including:
- Doom
- Star Fox
- Star Fox 2 (unreleased beta)
- Super Mario World 2: Yoshi's Island
SPC7110
Coprocessor used only by the following games:
- Far East of Eden Zero
- Far East of Eden Zero: Shounen Jump no Shou
- Momotarou Densetsu Happy
- Super Power League 4
DSP-3
Coprocessor used only by SD Gundam GX
DSP-4
Coprocessor used only by Top Gear 3000
ST010 / ST011 / ST018
SETA coprocessors used by very few games
BS-X (Broadcast Satellite)
Add-on unit sold only in Japan that played specially-made games that were
downloaded via satellite
BS-X Flashcart
Flash cartridge used by BS-X, as well as some standalone games by Asciisoft
Super Gameboy
Cartridge passthrough used for playing Gameboy games
Unsupported Controllers:
------------------------
Mouse
Super Scope
Justifier
Multitap (4-port and 5-port)
+1 -3
View File
@@ -1,4 +1,4 @@
#define BSNES_VERSION "0.020"
#define BSNES_VERSION "0.021"
#define BSNES_TITLE "bsnes v" BSNES_VERSION
#define MEMCORE bMemBus
@@ -31,11 +31,9 @@
#error "unsupported processor"
#endif
#include "lib/libinterp.h"
#include "lib/libsort.h"
#include "lib/libarray.h"
#include "lib/libvector.h"
#include "lib/libfile.h"
#include "lib/libstring.h"
#include "lib/libconfig.h"
+3 -1
View File
@@ -662,7 +662,9 @@ void bDSP::power()
{
ram = (uint8*) r_smp->get_spcram_handle();
memset( &m, 0, sizeof m );
memcpy( m.regs, initial_regs, sizeof m.regs );
//memcpy( m.regs, initial_regs, sizeof m.regs );
memset(m.regs, 0, sizeof m.regs);
REG(flg) = 0xe0;
// Internal state
for ( int i = voice_count; --i >= 0; )
+3 -3
View File
@@ -1,9 +1,9 @@
/*
libarray : version 0.08 ~byuu (2006-12-16)
libarray : version 0.09 ~byuu (2007-03-06)
*/
#ifndef __LIBARRAY
#define __LIBARRAY
#ifndef LIBARRAY_H
#define LIBARRAY_H
template<typename T> class array {
protected:
+3 -4
View File
@@ -1,5 +1,5 @@
/*
libbase : version 0.10 ~byuu (2007-05-27)
libbase : version 0.10 ~byuu (2007-06-04)
license: public domain
*/
@@ -16,6 +16,8 @@
#include <time.h>
#include <math.h>
#include <new>
#if defined(_MSC_VER)
#include <io.h>
#include <direct.h>
@@ -55,17 +57,14 @@
#define noinline __declspec(noinline)
#define inline inline
#define alwaysinline __forceinline
#define fastcall __fastcall
#elif defined(__GNUC__)
#define noinline __attribute__((noinline))
#define inline inline
#define alwaysinline __attribute__((always_inline))
#define fastcall __attribute__((fastcall))
#else
#define noinline
#define inline inline
#define alwaysinline inline
#define fastcall
#endif
/*****
+11 -1
View File
@@ -1,10 +1,20 @@
/*
libco_x86 : version 0.10 ~byuu (2007-04-18)
libco_x86 : version 0.10 ~byuu (2007-06-04)
license: public domain
*/
#ifndef LIBCO_H
#define LIBCO_H
#undef fastcall
#if defined(_MSC_VER)
#define fastcall __fastcall
#elif defined(__GNUC__)
#define fastcall __attribute__((fastcall))
#else
#error "fastcall undefined"
#endif
#define cocall fastcall
typedef void (*cothread_t);
+3 -3
View File
@@ -1,5 +1,5 @@
/*
libconfig : version 0.14 ~byuu (2007-05-27)
libconfig : version 0.14 ~byuu (2007-06-10)
license: public domain
*/
@@ -72,7 +72,7 @@ enum Format {
template<typename T> bool operator<=(T x) { return (T(data) <= x); }
template<typename T> bool operator< (T x) { return (T(data) < x); }
IntegerSetting(Config *parent, char *r_name, char *r_desc, uint r_format, uint r_data) {
IntegerSetting(Config *parent, const char *r_name, const char *r_desc, uint r_format, uint r_data) {
type = Setting::Integer;
name = strdup(r_name);
desc = strdup(r_desc);
@@ -103,7 +103,7 @@ string data;
bool operator==(const char *x) { return !strcmp(data, x); }
bool operator!=(const char *x) { return strcmp(data, x); }
StringSetting(Config *parent, char *r_name, char *r_desc, char *r_data) {
StringSetting(Config *parent, const char *r_name, const char *r_desc, char *r_data) {
type = Setting::String;
name = strdup(r_name);
desc = strdup(r_desc);
-455
View File
@@ -1,455 +0,0 @@
/*
libfile : version 0.07 ~byuu (2007-03-01)
*/
#ifndef __LIBFILE
#define __LIBFILE
//FreeBSD fix: do not use defines for libc functions
#undef feof
#undef ferror
/*****
* file object
*****/
class file {
public:
enum { mode_read, mode_write, mode_readwrite, mode_writeread };
enum { seek_start, seek_end, seek_back, seek_forward };
virtual void read(uint8 *data, uint length) = 0;
virtual uint8 read() = 0;
virtual void write(uint8 *data, uint length) = 0;
virtual void write(uint8 data) = 0;
virtual uint32 crc32();
virtual void seek(uint offset, uint mode = seek_start) = 0;
virtual void resize(uint size) = 0;
virtual uint offset() = 0;
virtual uint size() = 0;
virtual bool eof() = 0;
virtual bool open(const char *filename, uint mode) = 0;
virtual bool open() = 0;
virtual bool flush() = 0;
virtual bool close() = 0;
};
inline uint32 file::crc32() {
uint pos = offset(), i = size();
seek(0);
uint32 crc32 = 0xffffffff;
while(i--) {
crc32 = crc32_adjust(crc32, read());
}
seek(pos);
return ~crc32;
}
/*****
* c++ wrappers
*****/
inline void fread(file &s, uint8 *data, uint length) { s.read(data, length); }
inline uint8 fread(file &s) { return s.read(); }
inline uint8 fgetc(file &s) { return s.read(); }
inline uint fgetb(file &s) { return s.read(); }
inline void fwrite(file &s, uint8 *data, uint length) { s.write(data, length); }
inline void fwrite(file &s, uint8 data) { s.write(data); }
inline void fputc(uint8 data, file &s) { s.write(data); }
inline void fputb(file &s, uint8 data) { s.write(data); }
inline uint32 fcrc32(file &s) { return s.crc32(); }
inline void fseek(file &s, uint offset, uint mode = file::seek_start) { s.seek(offset, mode); }
inline void fresize(file &s, uint size) { s.resize(size); }
inline uint ftell(file &s) { return s.offset(); }
inline uint fsize(file &s) { return s.size(); }
inline bool feof(file &s) { return s.eof(); }
inline bool fopen(file &s, const char *filename, uint mode) { return s.open(filename, mode); }
inline bool fopen(file &s) { return s.open(); }
inline bool fflush(file &s) { return s.flush(); }
inline bool fclose(file &s) { return s.close(); }
/*****
* endian wrappers
*****/
inline uint8 fgetlb(file &s) { return fgetc(s); }
inline uint8 fgetmb(file &s) { return fgetc(s); }
inline uint16 fgetlw(file &s) {
return (fgetc(s)) | (fgetc(s) << 8);
}
inline uint16 fgetmw(file &s) {
return (fgetc(s) << 8) | (fgetc(s) << 8);
}
inline uint32 fgetld(file &s) {
return (fgetc(s)) | (fgetc(s) << 8) | (fgetc(s) << 16) | (fgetc(s) << 24);
}
inline uint32 fgetmd(file &s) {
return (fgetc(s) << 24) | (fgetc(s) << 16) | (fgetc(s) << 8) | (fgetc(s));
}
inline uint64 fgetlq(file &s) {
return ((uint64)fgetc(s) << 0) | ((uint64)fgetc(s) << 8) |
((uint64)fgetc(s) << 16) | ((uint64)fgetc(s) << 24) |
((uint64)fgetc(s) << 32) | ((uint64)fgetc(s) << 40) |
((uint64)fgetc(s) << 48) | ((uint64)fgetc(s) << 56);
}
inline uint64 fgetmq(file &s) {
return ((uint64)fgetc(s) << 56) | ((uint64)fgetc(s) << 48) |
((uint64)fgetc(s) << 40) | ((uint64)fgetc(s) << 32) |
((uint64)fgetc(s) << 24) | ((uint64)fgetc(s) << 16) |
((uint64)fgetc(s) << 8) | ((uint64)fgetc(s) << 0);
}
inline void fputlb(file &s, uint8 data) { fputc(data, s); }
inline void fputmb(file &s, uint8 data) { fputc(data, s); }
inline void fputlw(file &s, uint16 data) {
fputc(data >> 0, s);
fputc(data >> 8, s);
}
inline void fputmw(file &s, uint16 data) {
fputc(data >> 8, s);
fputc(data >> 0, s);
}
inline void fputld(file &s, uint32 data) {
fputc(data >> 0, s);
fputc(data >> 8, s);
fputc(data >> 16, s);
fputc(data >> 24, s);
}
inline void fputmd(file &s, uint32 data) {
fputc(data >> 24, s);
fputc(data >> 16, s);
fputc(data >> 8, s);
fputc(data >> 0, s);
}
inline void fputlq(file &s, uint64 data) {
fputc(data >> 0, s);
fputc(data >> 8, s);
fputc(data >> 16, s);
fputc(data >> 24, s);
fputc(data >> 32, s);
fputc(data >> 40, s);
fputc(data >> 48, s);
fputc(data >> 56, s);
}
inline void fputmq(file &s, uint64 data) {
fputc(data >> 56, s);
fputc(data >> 48, s);
fputc(data >> 40, s);
fputc(data >> 32, s);
fputc(data >> 24, s);
fputc(data >> 16, s);
fputc(data >> 8, s);
fputc(data >> 0, s);
}
/*****
* ramfile
*****/
class ramfile : public file {
private:
FILE *fp;
array<uint8> filedata;
char filename[1024];
uint filepos;
uint filesize;
uint filemode;
bool fileopen;
bool filevirtual;
public:
void read(uint8 *data, uint length) {
if(!fileopen || filemode == mode_write) { return; }
memcpy(data, filedata.get(filepos + length) + filepos, length);
filepos += length;
if(filepos > filesize)filepos = filesize;
}
uint8 read() {
if(!fileopen || filemode == mode_write) { return 0; }
if(eof() == true) { return 0xff; }
return filedata[filepos++];
}
void write(uint8 *data, uint length) {
if(!fileopen || filemode == mode_read) { return; }
memcpy(filedata.get(filepos + length) + filepos, data, length);
filepos += length;
if(filepos > filesize)filesize = filepos;
}
void write(uint8 data) {
if(!fileopen || filemode == mode_read) { return; }
filedata[filepos++] = data;
if(filepos > filesize)filesize = filepos;
}
void seek(uint offset, uint mode = seek_start) {
if(!fileopen) { return; }
switch(mode) {
case seek_start: filepos = offset; break;
case seek_end: filepos = filesize + offset; break;
case seek_back: filepos -= offset; break;
case seek_forward: filepos += offset; break;
}
if(filemode == mode_read) {
if(filepos > filesize)filepos = filesize;
} else {
if(filepos > filesize)filesize = filepos;
}
}
void resize(uint size) {
filesize = size;
if(filepos > filesize)filepos = filesize;
}
uint offset() {
if(!fileopen) { return 0; }
return filepos;
}
uint size() {
if(!fileopen) { return 0; }
return filesize;
}
bool eof() {
if(!fileopen) { return true; }
return (filepos >= filesize);
}
bool open(const char *fn, uint mode) {
if(fileopen) { return false; }
strcpy(filename, fn ? fn : "");
filevirtual = (*filename == 0);
filemode = mode;
switch(filemode) {
case mode_read:
case mode_readwrite:
if(filevirtual == true) {
filesize = 0;
} else {
fp = fopen(filename, "rb");
if(!fp) { return false; }
filesize = fsize(fp);
fread(filedata.get(filesize), 1, filesize, fp);
fclose(fp);
}
break;
default:
filesize = 0;
break;
}
filepos = 0;
fileopen = true;
return true;
}
bool open() {
return fileopen;
}
bool flush() {
if(!fileopen) { return false; }
switch(filemode) {
case mode_readwrite:
case mode_write:
case mode_writeread:
if(filevirtual == false) {
fp = fopen(filename, "wb");
if(!fp) { return false; }
fwrite(filedata.get(filesize), 1, filesize, fp);
fclose(fp);
}
break;
}
return true;
}
bool close() {
if(!fileopen) { return false; }
bool result = flush();
fileopen = false;
filedata.reset();
return result;
}
ramfile() {
fileopen = false;
}
~ramfile() {
if(fileopen) { close(); }
}
};
/*****
* diskfile
*****/
class diskfile : public file {
private:
FILE *fp;
uint filemode;
public:
void read(uint8 *data, uint length) {
if(!fp || filemode == mode_write) { return; }
fread(data, 1, length, fp);
}
uint8 read() {
if(!fp || filemode == mode_write) { return 0; }
if(eof() == true) { return 0xff; }
return fgetc(fp);
}
void write(uint8 *data, uint length) {
if(!fp || filemode == mode_read) { return; }
fwrite(data, 1, length, fp);
}
void write(uint8 data) {
if(!fp || filemode == mode_read) { return; }
fputc(data, fp);
}
void seek(uint offset, uint mode = seek_start) {
if(!fp) { return; }
switch(mode) {
default:
case seek_start: fseek(fp, offset, SEEK_SET); break;
case seek_end: fseek(fp, offset, SEEK_END); break;
case seek_back: fseek(fp, offset, SEEK_CUR); break;
case seek_forward: fseek(fp, offset, SEEK_CUR); break;
}
}
void resize(uint size) {
if(!fp) { return; }
fresize(fp, size);
}
uint offset() {
if(!fp) { return 0; }
return ftell(fp);
}
uint size() {
if(!fp) { return 0; }
uint pos = ftell(fp);
fseek(fp, 0, SEEK_END);
uint filesize = ftell(fp);
fseek(fp, pos, SEEK_SET);
return filesize;
}
bool eof() {
if(!fp) { return true; }
if(feof(fp)) {
seek(size(), seek_start);
return true;
}
return false;
}
bool open(const char *filename, uint mode) {
if(fp) { return false; }
filemode = mode;
char m[8];
switch(filemode) {
default:
case mode_read: strcpy(m, "rb"); break;
case mode_write: strcpy(m, "wb"); break;
case mode_readwrite: strcpy(m, "rb+"); break;
case mode_writeread: strcpy(m, "wb+"); break;
}
fp = fopen(filename, m);
if(!fp) { return false; }
return true;
}
bool open() {
return (fp != 0);
}
bool flush() {
if(!fp) { return false; }
fflush(fp);
return true;
}
bool close() {
if(!fp) { return false; }
fclose(fp);
fp = 0;
return true;
}
diskfile() {
fp = 0;
}
~diskfile() {
if(fp) { fclose(fp); }
}
};
/*****
* directory object
*****/
class directory {
public:
void open(const char *path) {}
void close() {}
uint read(char *filename, uint maxlength) { return 0; }
};
#endif
-341
View File
@@ -1,341 +0,0 @@
/*
libfunctor : version 0.01 ~byuu (2007-01-04)
*/
#ifndef __LIBFUNCTOR
#define __LIBFUNCTOR
template<typename T> struct functor;
template<typename T> struct functor_t;
/*****
* macros
*****/
#define base_functor \
functor *f; \
virtual operator bool() const { return f && (bool)(*f); } \
virtual functor *copy() const { return f->copy(); } \
functor &operator=(const functor *source) { if(f) { delete f; } f = (source->f) ? source->copy() : 0; return *this; } \
functor &operator=(const functor &source) { if(f) { delete f; } f = (source.f) ? source.copy() : 0; return *this; } \
functor(const functor &source) { /* ........................ */ f = (source.f) ? source.copy() : 0; } \
functor() : f(0) {} \
~functor() { if(f && f != this) { delete f; } }
#define base_global_functor \
operator bool() const { return proc; } \
functor_t *copy() const { return new functor_t(*this); } \
functor_t(const functor_t &source) { proc = source.proc; }
#define base_member_functor \
operator bool() const { return obj && proc; } \
functor_t *copy() const { return new functor_t(*this); } \
functor_t(const functor_t &source) { obj = source.obj; proc = source.proc; } \
C *obj;
/*****
* parameters = 0
*****/
template<typename R>
struct functor<R (*)()> { base_functor
virtual R operator()() const { return (*f)(); }
};
template<typename R>
struct functor_t<R (*)()> : public functor<R (*)()> { base_global_functor
R (*proc)();
R operator()() const { return (*proc)(); }
functor_t(R (*_proc)()) : proc(_proc) { this->f = this; }
};
template<typename C, typename R>
struct functor_t<R (C::*)()> : public functor<R (*)()> { base_member_functor
R (C::*proc)();
R operator()() const { return (obj->*proc)(); }
functor_t(C *_obj, R (C::*_proc)()) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R>
functor_t<R (*)()> make_functor(R (*proc)()) {
return functor_t<R (*)()>(proc);
}
template<typename C, typename R>
functor_t<R (C::*)()> make_functor(C *obj, R (C::*proc)()) {
return functor_t<R (C::*)()>(obj, proc);
}
/*****
* parameters = 1
*****/
template<typename R, typename P1>
struct functor<R (*)(P1)> { base_functor
virtual R operator()(P1 p1) const { return (*f)(p1); }
};
template<typename R, typename P1>
struct functor_t<R (*)(P1)> : public functor<R (*)(P1)> { base_global_functor
R (*proc)(P1);
R operator()(P1 p1) const { return (*proc)(p1); }
functor_t(R (*_proc)(P1)) : proc(_proc) { this->f = this; }
};
template<typename C, typename R, typename P1>
struct functor_t<R (C::*)(P1)> : public functor<R (*)(P1)> { base_member_functor
R (C::*proc)(P1);
R operator()(P1 p1) const { return (obj->*proc)(p1); }
functor_t(C *_obj, R (C::*_proc)(P1)) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R, typename P1>
functor_t<R (*)(P1)> make_functor(R (*proc)(P1)) {
return functor_t<R (*)(P1)>(proc);
}
template<typename C, typename R, typename P1>
functor_t<R (C::*)(P1)> make_functor(C *obj, R (C::*proc)(P1)) {
return functor_t<R (C::*)(P1)>(obj, proc);
}
/*****
* parameters = 2
*****/
template<typename R, typename P1, typename P2>
struct functor<R (*)(P1, P2)> { base_functor
virtual R operator()(P1 p1, P2 p2) const { return (*f)(p1, p2); }
};
template<typename R, typename P1, typename P2>
struct functor_t<R (*)(P1, P2)> : public functor<R (*)(P1, P2)> { base_global_functor
R (*proc)(P1, P2);
R operator()(P1 p1, P2 p2) const { return (*proc)(p1, p2); }
functor_t(R (*_proc)(P1, P2)) : proc(_proc) { this->f = this; }
};
template<typename C, typename R, typename P1, typename P2>
struct functor_t<R (C::*)(P1, P2)> : public functor<R (*)(P1, P2)> { base_member_functor
R (C::*proc)(P1, P2);
R operator()(P1 p1, P2 p2) const { return (obj->*proc)(p1, p2); }
functor_t(C *_obj, R (C::*_proc)(P1, P2)) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R, typename P1, typename P2>
functor_t<R (*)(P1, P2)> make_functor(R (*proc)(P1, P2)) {
return functor_t<R (*)(P1, P2)>(proc);
}
template<typename C, typename R, typename P1, typename P2>
functor_t<R (C::*)(P1, P2)> make_functor(C *obj, R (C::*proc)(P1, P2)) {
return functor_t<R (C::*)(P1, P2)>(obj, proc);
}
/*****
* parameters = 3
*****/
template<typename R, typename P1, typename P2, typename P3>
struct functor<R (*)(P1, P2, P3)> { base_functor
virtual R operator()(P1 p1, P2 p2, P3 p3) const { return (*f)(p1, p2, p3); }
};
template<typename R, typename P1, typename P2, typename P3>
struct functor_t<R (*)(P1, P2, P3)> : public functor<R (*)(P1, P2, P3)> { base_global_functor
R (*proc)(P1, P2, P3);
R operator()(P1 p1, P2 p2, P3 p3) const { return (*proc)(p1, p2, p3); }
functor_t(R (*_proc)(P1, P2, P3)) : proc(_proc) { this->f = this; }
};
template<typename C, typename R, typename P1, typename P2, typename P3>
struct functor_t<R (C::*)(P1, P2, P3)> : public functor<R (*)(P1, P2, P3)> { base_member_functor
R (C::*proc)(P1, P2, P3);
R operator()(P1 p1, P2 p2, P3 p3) const { return (obj->*proc)(p1, p2, p3); }
functor_t(C *_obj, R (C::*_proc)(P1, P2, P3)) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R, typename P1, typename P2, typename P3>
functor_t<R (*)(P1, P2, P3)> make_functor(R (*proc)(P1, P2, P3)) {
return functor_t<R (*)(P1, P2, P3)>(proc);
}
template<typename C, typename R, typename P1, typename P2, typename P3>
functor_t<R (C::*)(P1, P2, P3)> make_functor(C *obj, R (C::*proc)(P1, P2, P3)) {
return functor_t<R (C::*)(P1, P2, P3)>(obj, proc);
}
/*****
* parameters = 4
*****/
template<typename R, typename P1, typename P2, typename P3, typename P4>
struct functor<R (*)(P1, P2, P3, P4)> { base_functor
virtual R operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { return (*f)(p1, p2, p3, p4); }
};
template<typename R, typename P1, typename P2, typename P3, typename P4>
struct functor_t<R (*)(P1, P2, P3, P4)> : public functor<R (*)(P1, P2, P3, P4)> { base_global_functor
R (*proc)(P1, P2, P3, P4);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { return (*proc)(p1, p2, p3, p4); }
functor_t(R (*_proc)(P1, P2, P3, P4)) : proc(_proc) { this->f = this; }
};
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4>
struct functor_t<R (C::*)(P1, P2, P3, P4)> : public functor<R (*)(P1, P2, P3, P4)> { base_member_functor
R (C::*proc)(P1, P2, P3, P4);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { return (obj->*proc)(p1, p2, p3, p4); }
functor_t(C *_obj, R (C::*_proc)(P1, P2, P3, P4)) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R, typename P1, typename P2, typename P3, typename P4>
functor_t<R (*)(P1, P2, P3, P4)> make_functor(R (*proc)(P1, P2, P3, P4)) {
return functor_t<R (*)(P1, P2, P3, P4)>(proc);
}
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4>
functor_t<R (C::*)(P1, P2, P3, P4)> make_functor(C *obj, R (C::*proc)(P1, P2, P3, P4)) {
return functor_t<R (C::*)(P1, P2, P3, P4)>(obj, proc);
}
/*****
* parameters = 5
*****/
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5>
struct functor<R (*)(P1, P2, P3, P4, P5)> { base_functor
virtual R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const { return (*f)(p1, p2, p3, p4, p5); }
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5>
struct functor_t<R (*)(P1, P2, P3, P4, P5)> : public functor<R (*)(P1, P2, P3, P4, P5)> { base_global_functor
R (*proc)(P1, P2, P3, P4, P5);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const { return (*proc)(p1, p2, p3, p4, p5); }
functor_t(R (*_proc)(P1, P2, P3, P4, P5)) : proc(_proc) { this->f = this; }
};
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4, typename P5>
struct functor_t<R (C::*)(P1, P2, P3, P4, P5)> : public functor<R (*)(P1, P2, P3, P4, P5)> { base_member_functor
R (C::*proc)(P1, P2, P3, P4, P5);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const { return (obj->*proc)(p1, p2, p3, p4, p5); }
functor_t(C *_obj, R (C::*_proc)(P1, P2, P3, P4, P5)) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5>
functor_t<R (*)(P1, P2, P3, P4, P5)> make_functor(R (*proc)(P1, P2, P3, P4, P5)) {
return functor_t<R (*)(P1, P2, P3, P4, P5)>(proc);
}
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4, typename P5>
functor_t<R (C::*)(P1, P2, P3, P4, P5)> make_functor(C *obj, R (C::*proc)(P1, P2, P3, P4, P5)) {
return functor_t<R (C::*)(P1, P2, P3, P4, P5)>(obj, proc);
}
/*****
* parameters = 6
*****/
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
struct functor<R (*)(P1, P2, P3, P4, P5, P6)> { base_functor
virtual R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const { return (*f)(p1, p2, p3, p4, p5, p6); }
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
struct functor_t<R (*)(P1, P2, P3, P4, P5, P6)> : public functor<R (*)(P1, P2, P3, P4, P5, P6)> { base_global_functor
R (*proc)(P1, P2, P3, P4, P5, P6);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const { return (*proc)(p1, p2, p3, p4, p5, p6); }
functor_t(R (*_proc)(P1, P2, P3, P4, P5, P6)) : proc(_proc) { this->f = this; }
};
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
struct functor_t<R (C::*)(P1, P2, P3, P4, P5, P6)> : public functor<R (*)(P1, P2, P3, P4, P5, P6)> { base_member_functor
R (C::*proc)(P1, P2, P3, P4, P5, P6);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const { return (obj->*proc)(p1, p2, p3, p4, p5, p6); }
functor_t(C *_obj, R (C::*_proc)(P1, P2, P3, P4, P5, P6)) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
functor_t<R (*)(P1, P2, P3, P4, P5, P6)> make_functor(R (*proc)(P1, P2, P3, P4, P5, P6)) {
return functor_t<R (*)(P1, P2, P3, P4, P5, P6)>(proc);
}
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
functor_t<R (C::*)(P1, P2, P3, P4, P5, P6)> make_functor(C *obj, R (C::*proc)(P1, P2, P3, P4, P5, P6)) {
return functor_t<R (C::*)(P1, P2, P3, P4, P5, P6)>(obj, proc);
}
/*****
* parameters = 7
*****/
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
struct functor<R (*)(P1, P2, P3, P4, P5, P6, P7)> { base_functor
virtual R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const { return (*f)(p1, p2, p3, p4, p5, p6, p7); }
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
struct functor_t<R (*)(P1, P2, P3, P4, P5, P6, P7)> : public functor<R (*)(P1, P2, P3, P4, P5, P6, P7)> { base_global_functor
R (*proc)(P1, P2, P3, P4, P5, P6, P7);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const { return (*proc)(p1, p2, p3, p4, p5, p6, p7); }
functor_t(R (*_proc)(P1, P2, P3, P4, P5, P6, P7)) : proc(_proc) { this->f = this; }
};
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
struct functor_t<R (C::*)(P1, P2, P3, P4, P5, P6, P7)> : public functor<R (*)(P1, P2, P3, P4, P5, P6, P7)> { base_member_functor
R (C::*proc)(P1, P2, P3, P4, P5, P6, P7);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const { return (obj->*proc)(p1, p2, p3, p4, p5, p6, p7); }
functor_t(C *_obj, R (C::*_proc)(P1, P2, P3, P4, P5, P6, P7)) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
functor_t<R (*)(P1, P2, P3, P4, P5, P6, P7)> make_functor(R (*proc)(P1, P2, P3, P4, P5, P6, P7)) {
return functor_t<R (*)(P1, P2, P3, P4, P5, P6, P7)>(proc);
}
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
functor_t<R (C::*)(P1, P2, P3, P4, P5, P6, P7)> make_functor(C *obj, R (C::*proc)(P1, P2, P3, P4, P5, P6, P7)) {
return functor_t<R (C::*)(P1, P2, P3, P4, P5, P6, P7)>(obj, proc);
}
/*****
* parameters = 8
*****/
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
struct functor<R (*)(P1, P2, P3, P4, P5, P6, P7, P8)> { base_functor
virtual R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const { return (*f)(p1, p2, p3, p4, p5, p6, p7, p8); }
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
struct functor_t<R (*)(P1, P2, P3, P4, P5, P6, P7, P8)> : public functor<R (*)(P1, P2, P3, P4, P5, P6, P7, P8)> { base_global_functor
R (*proc)(P1, P2, P3, P4, P5, P6, P7, P8);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const { return (*proc)(p1, p2, p3, p4, p5, p6, p7, p8); }
functor_t(R (*_proc)(P1, P2, P3, P4, P5, P6, P7, P8)) : proc(_proc) { this->f = this; }
};
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
struct functor_t<R (C::*)(P1, P2, P3, P4, P5, P6, P7, P8)> : public functor<R (*)(P1, P2, P3, P4, P5, P6, P7, P8)> { base_member_functor
R (C::*proc)(P1, P2, P3, P4, P5, P6, P7, P8);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const { return (obj->*proc)(p1, p2, p3, p4, p5, p6, p7, p8); }
functor_t(C *_obj, R (C::*_proc)(P1, P2, P3, P4, P5, P6, P7, P8)) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
functor_t<R (*)(P1, P2, P3, P4, P5, P6, P7, P8)> make_functor(R (*proc)(P1, P2, P3, P4, P5, P6, P7, P8)) {
return functor_t<R (*)(P1, P2, P3, P4, P5, P6, P7, P8)>(proc);
}
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
functor_t<R (C::*)(P1, P2, P3, P4, P5, P6, P7, P8)> make_functor(C *obj, R (C::*proc)(P1, P2, P3, P4, P5, P6, P7, P8)) {
return functor_t<R (C::*)(P1, P2, P3, P4, P5, P6, P7, P8)>(obj, proc);
}
/*****
* epilogue
*****/
#undef base_functor
#undef base_global_functor
#undef base_member_functor
#endif
-73
View File
@@ -1,73 +0,0 @@
/*
libinterp : version 0.01 ~byuu (2007-02-03)
*/
#ifndef __LIBINTERP
#define __LIBINTERP
static inline
double interpolate_point(
double mu,
double y0, double y1
) {
return mu < 0.5 ? y0 : y1;
}
static inline
double interpolate_linear(
double mu,
double y0, double y1
) {
return y0 + mu * (y1 - y0);
}
static inline
double interpolate_cosine(
double mu,
double y0, double y1
) {
mu = (1.0 - cos(mu * 3.14159265)) / 2.0;
return y0 + mu * (y1 - y0);
}
static inline
double interpolate_cubic(
double mu,
double y0, double y1, double y2, double y3
) {
double a0 = y3 - y2 - y0 + y1;
double a1 = y0 - y1 - a0;
double a2 = y2 - y0;
double a3 = y1;
return a0 * mu * mu * mu +
a1 * mu * mu +
a2 * mu +
a3;
}
/*
tension: (0 = normal, -1 = low, +1 = high)
bias: (0 = even, -n = left, +n = right)
*/
static inline
double interpolate_hermite(
double mu, double tension, double bias,
double y0, double y1, double y2, double y3
) {
double mu0 = ( (y1 - y0) * (1.0 + bias) * (1.0 - tension) / 2.0 ) +
( (y2 - y1) * (1.0 - bias) * (1.0 - tension) / 2.0 );
double mu1 = ( (y2 - y1) * (1.0 + bias) * (1.0 - tension) / 2.0 ) +
( (y3 - y2) * (1.0 - bias) * (1.0 - tension) / 2.0 );
double mu2 = mu * mu;
double mu3 = mu * mu * mu;
double a0 = 2.0 * mu3 - 3.0 * mu2 + 1.0;
double a1 = mu3 - 2.0 * mu2 + mu;
double a2 = mu3 - mu2;
double a3 = -2.0 * mu3 + 3.0 * mu2;
return a0 * y1 +
a1 * mu0 +
a2 * mu1 +
a3 * y2;
}
#endif
+24
View File
@@ -7,6 +7,28 @@
namespace keymap {
//TODO: use lookup table for find() functions
static char keytable[][64] = {
"none",
"esc",
"f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12",
"print_screen", "sys_req", "scroll_lock", "pause", "brk",
"grave", "tilde",
"num_1", "exclamation",
"num_2", "at",
"num_3", "pound",
"num_4", "dollar",
"num_5", "percent",
"num_6", "power",
"num_7", "ampersand",
"num_8", "asterisk",
"num_9", "lparenthesis",
"num_0", "rparenthesis",
"minus", "underscore",
"equal", "plus",
"backspace",
};
enum {
none = 0x0000,
@@ -108,6 +130,8 @@ enum {
rsuper,
menu,
limit, //not an actual key -- marks the end of linear key entries
joypad_flag = 0x8000,
joypad_nummask = 0x7f00,
joypad_keymask = 0x00ff,
+2 -2
View File
@@ -2,8 +2,8 @@
libsort : version 0.01 ~byuu (2006-11-15)
*/
#ifndef __LIBSORT
#define __LIBSORT
#ifndef LIBSORT_H
#define LIBSORT_H
template<typename T>
void sort(T list[], uint length) {
+27 -30
View File
@@ -1,9 +1,9 @@
/*
libstring : version 0.17 ~byuu (2007-05-20)
libstring : version 0.18 ~byuu (2007-06-06)
*/
#ifndef __LIBSTRING
#define __LIBSTRING
#ifndef LIBSTRING_H
#define LIBSTRING_H
#include "libbase.h"
#include "libvector.h"
@@ -189,35 +189,32 @@ uint size;
~string() { safe_free(s); }
const char *operator()();
char &operator[](const uint);
string &operator= (const int);
string &operator= (const char *);
string &operator= (const string &);
string &operator+=(const int);
string &operator+=(const char *);
string &operator+=(const string &);
bool operator==(const char *);
bool operator==(const string &);
bool operator!=(const char *);
bool operator!=(const string &);
bool operator< (const char *);
bool operator< (const string &);
bool operator<=(const char *);
bool operator<=(const string &);
bool operator> (const char *);
bool operator> (const string &);
bool operator>=(const char *);
bool operator>=(const string &);
operator const char*() const { return s; }
const char* operator()() const { return s; }
char& operator[](const uint);
string operator+(const int);
string operator+(const char *);
string operator+(const string &);
string& operator=(const int);
string& operator=(const char*);
string& operator=(const string&);
string& operator<<(const int);
string& operator<<(const char*);
string& operator<<(const string&);
bool operator==(const char*);
bool operator==(const string&);
bool operator!=(const char*);
bool operator!=(const string&);
bool operator< (const char*);
bool operator< (const string&);
bool operator<=(const char*);
bool operator<=(const string&);
bool operator> (const char*);
bool operator> (const string&);
bool operator>=(const char*);
bool operator>=(const string&);
};
string operator+(const int, const string &);
string operator+(const char *, const string &);
inline void swap(string &x, string &y) { x.swap(y); }
#endif //__LIBSTRING
#endif //LIBSTRING_H
+3 -39
View File
@@ -1,7 +1,3 @@
const char *string::operator()() {
return s;
}
char &string::operator[](const uint index) {
reserve(index);
return s[index];
@@ -22,17 +18,17 @@ string &string::operator=(const string &str) {
return *this;
}
string &string::operator+=(const int num) {
string& string::operator<<(const int num) {
strcat(*this, strfmt("%d", num));
return *this;
}
string &string::operator+=(const char *str) {
string& string::operator<<(const char* str) {
strcat(*this, str);
return *this;
}
string &string::operator+=(const string &str) {
string& string::operator<<(const string& str) {
strcat(*this, str);
return *this;
}
@@ -49,35 +45,3 @@ bool string::operator> (const char *str) { return strcmp(strptr(*this), str)
bool string::operator> (const string &str) { return strcmp(strptr(*this), strptr(str)) > 0; }
bool string::operator>=(const char *str) { return strcmp(strptr(*this), str) >= 0; }
bool string::operator>=(const string &str) { return strcmp(strptr(*this), strptr(str)) >= 0; }
string string::operator+(const int num) {
string temp(*this);
strcat(temp, strfmt("%d", num));
return temp;
}
string string::operator+(const char *str) {
string temp(*this);
strcat(temp, str);
return temp;
}
string string::operator+(const string &str) {
string temp(*this);
strcat(temp, str);
return temp;
}
//
string operator+(const int x, const string &y) {
string temp(strfmt("%d", x));
strcat(temp, y);
return temp;
}
string operator+(const char *x, const string &y) {
string temp(x);
strcat(temp, y);
return temp;
}
+8 -19
View File
@@ -40,13 +40,14 @@ uint get_screen_height() { return gdk_screen_height(); }
//
noinline bool gtk_file_load(Window &owner, char *filename, const char *filter, const char *path) {
bool file_load(Window *owner, char *filename, const char *filter, const char *path) {
strcpy(filename, "");
GtkWidget *dialog = gtk_file_chooser_dialog_new("Load File",
GTK_WINDOW(owner.info.window), GTK_FILE_CHOOSER_ACTION_OPEN,
owner ? GTK_WINDOW(owner->info.window) : (GtkWindow*)0,
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, 0);
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, (const gchar*)0);
if(path && strcmp(path, "")) {
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
@@ -62,13 +63,14 @@ GtkWidget *dialog = gtk_file_chooser_dialog_new("Load File",
return strcmp(filename, ""); //return true if filename != ""
}
noinline bool gtk_file_save(Window &owner, char *filename, const char *filter, const char *path) {
bool file_save(Window *owner, char *filename, const char *filter, const char *path) {
strcpy(filename, "");
GtkWidget *dialog = gtk_file_chooser_dialog_new("Save File",
GTK_WINDOW(owner.info.window), GTK_FILE_CHOOSER_ACTION_SAVE,
owner ? GTK_WINDOW(owner->info.window) : (GtkWindow*)0,
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, 0);
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, (const gchar*)0);
if(path && strcmp(path, "")) {
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
@@ -85,19 +87,6 @@ GtkWidget *dialog = gtk_file_chooser_dialog_new("Save File",
return strcmp(filename, ""); //return true if filename != ""
}
//FreeBSD 6.2-amd64 bug workaround for file_load() + file_save()
//gdb reveals stack corruption when calling gtk_file_chooset_dialog_new() from inside
//a member function. however, calling function with nesting sidesteps the bug ...
//gdb shows that the corruption occurs inside a GTK+ internal library function ...
bool file_load(Window &owner, char *filename, const char *filter, const char *path) {
return gtk_file_load(owner, filename, filter, path);
}
bool file_save(Window &owner, char *filename, const char *filter, const char *path) {
return gtk_file_save(owner, filename, filter, path);
}
//
uint16 translate_key(uint key) {
+12 -10
View File
@@ -1,5 +1,5 @@
/*
libui_gtk ~byuu (2007-05-27)
libui_gtk ~byuu (2007-06-06)
license: public domain
*/
@@ -28,8 +28,8 @@ bool events_pending();
uint get_screen_width();
uint get_screen_height();
bool file_load(Window &owner, char *filename, const char *filter, const char *path = "");
bool file_save(Window &owner, char *filename, const char *filter, const char *path = "");
bool file_load(Window *owner, char *filename, const char *filter, const char *path = "");
bool file_save(Window *owner, char *filename, const char *filter, const char *path = "");
uint16 translate_key(uint key);
@@ -53,20 +53,22 @@ enum Style {
MenuBar menu;
void create(uint style, uint width, uint height, const char *caption = "");
void set_text(const char *str, ...);
void set_text(const char *str);
void set_background_color(uint8 r, uint8 g, uint8 b);
void focus();
bool focused();
void move(uint x, uint y);
void resize(uint width, uint height);
virtual void show();
virtual void hide();
virtual bool close() { return true; }
virtual void keydown(uint16 key) {}
virtual void keyup(uint16 key) {}
void show(bool state);
bool visible();
void fullscreen();
void unfullscreen();
void fullscreen(bool state);
bool is_fullscreen();
virtual int message(uint id, void *param = 0) {}
virtual void clicked(Control&) {}
virtual void changed(Control&) {}
virtual bool message(uint id, uintptr_t param = 0) { return true; }
//private:
struct {
+21 -46
View File
@@ -321,13 +321,8 @@ void Label::create(Window &r_owner, uint style, uint x, uint y, uint width, uint
gtk_widget_show(widget);
}
void Label::set_text(const char *str, ...) {
va_list args;
va_start(args, str);
string temp;
vsprintf(temp, str, args);
va_end(args);
gtk_label_set_label(GTK_LABEL(widget), strptr(temp));
void Label::set_text(const char *str) {
gtk_label_set_label(GTK_LABEL(widget), str);
}
/*****
@@ -345,13 +340,8 @@ void Button::create(Window &r_owner, uint style, uint x, uint y, uint width, uin
g_signal_connect_swapped(G_OBJECT(widget), "clicked", G_CALLBACK(libui_control_clicked), (gpointer)this);
}
void Button::set_text(const char *str, ...) {
va_list args;
va_start(args, str);
string temp;
vsprintf(temp, str, args);
va_end(args);
gtk_button_set_label(GTK_BUTTON(widget), strptr(temp));
void Button::set_text(const char *str) {
gtk_button_set_label(GTK_BUTTON(widget), str);
}
/*****
@@ -447,17 +437,11 @@ void Editbox::create(Window &r_owner, uint style, uint x, uint y, uint width, ui
gtk_widget_show(widget);
}
void Editbox::set_text(const char *str, ...) {
va_list args;
va_start(args, str);
string temp;
vsprintf(temp, str, args);
va_end(args);
void Editbox::set_text(const char *str) {
if(multiline == false) {
gtk_entry_set_text(GTK_ENTRY(widget), strptr(temp));
gtk_entry_set_text(GTK_ENTRY(widget), str);
} else {
gtk_text_buffer_set_text(buffer, strptr(temp), -1);
gtk_text_buffer_set_text(buffer, str, -1);
}
}
@@ -539,28 +523,16 @@ void Listbox::set_column_width(uint column, uint width) {
gtk_tree_view_column_set_max_width(column_list[column], width);
}
void Listbox::add_item(const char *data, ...) {
va_list args;
va_start(args, data);
string temp;
vsprintf(temp, data, args);
va_end(args);
void Listbox::add_item(const char *data) {
stringarray part;
split(part, "|", temp);
split(part, "|", data);
gtk_list_store_append(store, &iter);
for(uint i = 0; i < count(part); i++) {
gtk_list_store_set(store, &iter, i, strptr(part[i]), -1);
}
}
void Listbox::set_item(uint index, const char *data, ...) {
va_list args;
va_start(args, data);
string temp;
vsprintf(temp, data, args);
va_end(args);
void Listbox::set_item(uint index, const char *data) {
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(subwidget));
for(uint i = 0; i <= index; i++) {
(i == 0) ?
@@ -569,14 +541,14 @@ GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(subwidget));
}
stringarray part;
split(part, "|", temp);
split(part, "|", data);
for(uint i = 0; i < count(part); i++) {
gtk_list_store_set(store, &iter, i, strptr(part[i]), -1);
}
}
int Listbox::get_selection() {
//... because gtk_tree_view_get_selected_row(GTK_TREE_VIEW(subwidget)) would be too easy ...
int Listbox::get_selection() {
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(subwidget));
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(subwidget));
if(gtk_tree_model_get_iter_first(model, &iter) == false) { return -1; }
@@ -588,18 +560,21 @@ GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(subwidget));
return -1;
}
void Listbox::set_selection(int index) {
//... because gtk_tree_view_set_selected_row(GTK_TREE_VIEW(subwidget), index) would be too easy ...
void Listbox::set_selection(int index) {
int current = get_selection();
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(subwidget));
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(subwidget));
gtk_tree_selection_unselect_all(selection);
if(index < 0) { return; }
if(gtk_tree_model_get_iter_first(model, &iter) == false) { return; }
if(index == 0) { gtk_tree_selection_select_iter(selection, &iter); return; }
if(index < 0) { goto end; }
if(gtk_tree_model_get_iter_first(model, &iter) == false) { goto end; }
if(index == 0) { gtk_tree_selection_select_iter(selection, &iter); goto end; }
for(uint i = 1; i < 100000; i++) {
if(gtk_tree_model_iter_next(model, &iter) == false) { return; }
if(index == i) { gtk_tree_selection_select_iter(selection, &iter); return; }
if(gtk_tree_model_iter_next(model, &iter) == false) { goto end; }
if(index == i) { gtk_tree_selection_select_iter(selection, &iter); goto end; }
}
end:
if(current != index) { owner->message(Message::Changed, (uintptr_t)this); }
}
void Listbox::reset() {
+5 -5
View File
@@ -148,12 +148,12 @@ class Frame : public Control { public:
class Label : public Control { public:
void create(Window &owner, uint style, uint x, uint y, uint width, uint height, const char *caption = "");
void set_text(const char *str, ...);
void set_text(const char *str);
};
class Button : public Control { public:
void create(Window &owner, uint style, uint x, uint y, uint width, uint height, const char *caption = "");
void set_text(const char *str, ...);
void set_text(const char *str);
};
class Checkbox : public Control { public:
@@ -185,7 +185,7 @@ enum {
};
void create(Window &owner, uint style, uint x, uint y, uint width, uint height, const char *caption = "");
void set_text(const char *str, ...);
void set_text(const char *str);
uint get_text(char *str, uint length);
private:
@@ -210,8 +210,8 @@ enum {
void create(Window &owner, uint style, uint x, uint y, uint width, uint height, const char *columns = "");
void autosize_columns();
void set_column_width(uint column, uint width);
void add_item(const char *data, ...);
void set_item(uint index, const char *data, ...);
void add_item(const char *data);
void set_item(uint index, const char *data);
int get_selection();
void set_selection(int index);
void reset();
+35 -12
View File
@@ -6,25 +6,25 @@ gint libui_window_close(GtkWidget *w, GdkEventAny *any, Window *window) {
}
gint libui_window_keydown(GtkWidget *w, GdkEventKey *key, Window *window) {
if(window) { window->message(Message::KeyDown, (void*)libui::translate_key(key->keyval)); }
if(window) { window->message(Message::KeyDown, libui::translate_key(key->keyval)); }
return FALSE;
}
gint libui_window_keyup(GtkWidget *w, GdkEventKey *key, Window *window) {
if(window) { window->message(Message::KeyUp, (void*)libui::translate_key(key->keyval)); }
if(window) { window->message(Message::KeyUp, libui::translate_key(key->keyval)); }
return FALSE;
}
void libui_control_clicked(Control *control) {
if(control && control->owner) { control->owner->message(Message::Clicked, control); }
if(control && control->owner) { control->owner->message(Message::Clicked, (uintptr_t)control); }
}
void libui_control_changed(Control *control) {
if(control && control->owner) { control->owner->message(Message::Changed, control); }
if(control && control->owner) { control->owner->message(Message::Changed, (uintptr_t)control); }
}
void libui_control_double_clicked(Control *control) {
if(control && control->owner) { control->owner->message(Message::DoubleClicked, control); }
if(control && control->owner) { control->owner->message(Message::DoubleClicked, (uintptr_t)control); }
}
void Window::create(uint style, uint width, uint height, const char *caption) {
@@ -56,6 +56,10 @@ void Window::focus() {
gtk_window_present(GTK_WINDOW(info.window));
}
bool Window::focused() {
return GTK_WIDGET_HAS_FOCUS(info.window);
}
void Window::move(uint x, uint y) {
//if window was centered before, GTK+ will ignore move requests,
//therfore we must turn off auto-centering.
@@ -75,13 +79,32 @@ void Window::hide() {
gtk_widget_hide(info.window);
}
void Window::set_text(const char *str, ...) {
va_list args;
va_start(args, str);
string temp;
vsprintf(temp, str, args);
va_end(args);
gtk_window_set_title(GTK_WINDOW(info.window), strptr(temp));
void Window::show(bool state) {
(state == true) ? show() : hide();
}
bool Window::visible() {
return GTK_WIDGET_VISIBLE(info.window);
}
void Window::fullscreen() {
gtk_window_fullscreen(GTK_WINDOW(info.window));
}
void Window::unfullscreen() {
gtk_window_unfullscreen(GTK_WINDOW(info.window));
}
void Window::fullscreen(bool state) {
(state == true) ? fullscreen() : unfullscreen();
}
bool Window::is_fullscreen() {
return false;
};
void Window::set_text(const char *str) {
gtk_window_set_title(GTK_WINDOW(info.window), str);
}
void Window::set_background_color(uint8 r, uint8 g, uint8 b) {
+17 -4
View File
@@ -81,7 +81,7 @@ uint get_screen_height() { return GetSystemMetrics(SM_CYSCREEN); }
//
bool file_load(Window &owner, char *filename, const char *filter, const char *path) {
bool file_load(Window *owner, char *filename, const char *filter, const char *path) {
string dir, f;
strcpy(dir, path ? path : "");
replace(dir, "/", "\\");
@@ -111,7 +111,7 @@ OPENFILENAME ofn;
strcpy(filename, "");
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = owner.info.hwnd;
ofn.hwndOwner = owner ? owner->info.hwnd : 0;
ofn.lpstrFilter = pf;
ofn.lpstrInitialDir = strptr(dir);
ofn.lpstrFile = filename;
@@ -122,7 +122,7 @@ OPENFILENAME ofn;
return GetOpenFileName(&ofn);
}
bool file_save(Window &owner, char *filename, const char *filter, const char *path) {
bool file_save(Window *owner, char *filename, const char *filter, const char *path) {
string dir, f;
strcpy(dir, path ? path : "");
replace(dir, "/", "\\");
@@ -152,7 +152,7 @@ OPENFILENAME ofn;
strcpy(filename, "");
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = owner.info.hwnd;
ofn.hwndOwner = owner ? owner->info.hwnd : 0;
ofn.lpstrFilter = pf;
ofn.lpstrInitialDir = strptr(dir);
ofn.lpstrFile = filename;
@@ -170,6 +170,19 @@ uint16 translate_key(uint key) {
case VK_ESCAPE: return keymap::esc;
case VK_F1: return keymap::f1;
case VK_F2: return keymap::f2;
case VK_F3: return keymap::f3;
case VK_F4: return keymap::f4;
case VK_F5: return keymap::f5;
case VK_F6: return keymap::f6;
case VK_F7: return keymap::f7;
case VK_F8: return keymap::f8;
case VK_F9: return keymap::f9;
case VK_F10: return keymap::f10;
case VK_F11: return keymap::f11;
case VK_F12: return keymap::f12;
case VK_TAB: return keymap::tab;
case VK_RETURN: return keymap::enter;
case VK_SPACE: return keymap::space;
+12 -4
View File
@@ -1,5 +1,5 @@
/*
libui_win ~byuu (2007-05-28)
libui_win ~byuu (2007-06-10)
license: public domain
*/
@@ -32,8 +32,8 @@ bool events_pending();
uint get_screen_width();
uint get_screen_height();
bool file_load(Window &owner, char *filename, const char *filter, const char *path = "");
bool file_save(Window &owner, char *filename, const char *filter, const char *path = "");
bool file_load(Window *owner, char *filename, const char *filter, const char *path = "");
bool file_save(Window *owner, char *filename, const char *filter, const char *path = "");
uint16 translate_key(uint key);
@@ -60,12 +60,19 @@ MenuBar menu;
void set_text(const char *str, ...);
void set_background_color(uint8 r, uint8 g, uint8 b);
void focus();
bool focused();
void move(uint x, uint y);
void resize(uint width, uint height);
virtual void show();
virtual void hide();
void show(bool state);
bool visible();
void fullscreen();
void unfullscreen();
void fullscreen(bool state);
bool is_fullscreen();
virtual int message(uint id, void *param = 0) { return 0; }
virtual bool message(uint id, uintptr_t param = 0) { return true; }
void move(Control &control, uint x, uint y);
void attach(Control &control);
@@ -78,6 +85,7 @@ MenuBar menu;
//private:
struct {
uint width, height;
bool fullscreen;
HWND hwnd;
HWND hwnd_resize;
+20 -7
View File
@@ -4,6 +4,10 @@ namespace libui {
* Control
*****/
void Control::move(uint x, uint y) {
SetWindowPos(hwnd, 0, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
}
void Control::resize(uint width, uint height) {
SetWindowPos(hwnd, 0, 0, 0, width, height, SWP_NOZORDER | SWP_NOMOVE);
}
@@ -137,13 +141,13 @@ void MenuCheckItem::create(MenuGroup &r_owner, const char *caption) {
void MenuCheckItem::check() {
if(checked() == true)return;
CheckMenuItem(parent, id, MF_CHECKED);
owner->message(Message::Clicked, this);
owner->message(Message::Clicked, (uintptr_t)this);
}
void MenuCheckItem::uncheck() {
if(checked() == false)return;
CheckMenuItem(parent, id, MF_UNCHECKED);
owner->message(Message::Clicked, this);
owner->message(Message::Clicked, (uintptr_t)this);
}
void MenuCheckItem::check(bool state) {
@@ -180,7 +184,7 @@ void MenuRadioItem::check() {
for(uint i = 0; i < group.count(); i++) {
CheckMenuItem(parent, group[i].id, (id == group[i].id) ? MF_CHECKED : MF_UNCHECKED);
}
owner->message(Message::Clicked, this);
owner->message(Message::Clicked, (uintptr_t)this);
}
bool MenuRadioItem::checked() {
@@ -355,11 +359,20 @@ long __stdcall label_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
BeginPaint(hwnd, &ps);
RECT rc;
char t[4096];
GetWindowText(hwnd, t, 4095);
GetWindowText(hwnd, t, 4095); //TODO: use internal buffer, so length is not limited ...
GetClientRect(hwnd, &rc);
SetTextColor(ps.hdc, RGB(0, 0, 0));
SetBkMode(ps.hdc, TRANSPARENT);
SelectObject(ps.hdc, (HGDIOBJ)libui::font.variable);
//center text if text height < control height, otherwise draw from top left corner
RECT trc;
GetClientRect(hwnd, &trc);
DrawText(ps.hdc, t, strlen(t), &trc, DT_CALCRECT);
if(trc.bottom < rc.bottom) {
rc.top = (rc.bottom - trc.bottom) / 2;
rc.bottom = rc.top + trc.bottom;
}
//
DrawText(ps.hdc, t, strlen(t), &rc, DT_END_ELLIPSIS | DT_NOPREFIX);
EndPaint(hwnd, &ps);
} break;
@@ -419,13 +432,13 @@ void Checkbox::create(Window &r_owner, uint style, uint x, uint y, uint width, u
void Checkbox::check() {
if(checked() == true)return;
SendMessage(hwnd, BM_SETCHECK, (WPARAM)TRUE, 0);
owner->message(Message::Clicked, this);
owner->message(Message::Clicked, (uintptr_t)this);
}
void Checkbox::uncheck() {
if(checked() == false)return;
SendMessage(hwnd, BM_SETCHECK, (WPARAM)FALSE, 0);
owner->message(Message::Clicked, this);
owner->message(Message::Clicked, (uintptr_t)this);
}
void Checkbox::check(bool state) {
@@ -456,7 +469,7 @@ void Radiobox::check() {
for(uint i = 0; i < group.count(); i++) {
SendMessage(group[i].hwnd, BM_SETCHECK, (group[i].hwnd == hwnd) ? (WPARAM)TRUE : (WPARAM)FALSE, 0);
}
owner->message(Message::Clicked, this);
owner->message(Message::Clicked, (uintptr_t)this);
}
bool Radiobox::checked() {
+1
View File
@@ -25,6 +25,7 @@ namespace ControlType {
class Control { public:
uint type;
void move(uint x, uint y);
void resize(uint width, uint height);
void focus();
+49 -7
View File
@@ -33,11 +33,11 @@ long Window::wndproc(HWND hwnd, uint msg, WPARAM wparam, LPARAM lparam) {
} break;
case WM_KEYDOWN: {
message(Message::KeyDown, (void*)libui::translate_key(wparam));
message(Message::KeyDown, libui::translate_key(wparam));
} break;
case WM_KEYUP: {
message(Message::KeyUp, (void*)libui::translate_key(wparam));
message(Message::KeyUp, libui::translate_key(wparam));
} break;
case WM_COMMAND: {
@@ -68,7 +68,7 @@ long Window::wndproc(HWND hwnd, uint msg, WPARAM wparam, LPARAM lparam) {
//emit Message::Clicked message directly
case ControlType::MenuItem:
case ControlType::Button: {
message(Message::Clicked, &control);
message(Message::Clicked, (uintptr_t)&control);
} break;
}
@@ -84,7 +84,7 @@ long Window::wndproc(HWND hwnd, uint msg, WPARAM wparam, LPARAM lparam) {
switch(control.type) {
case ControlType::Slider: {
message(Message::Changed, &control);
message(Message::Changed, (uintptr_t)&control);
} break;
}
@@ -104,12 +104,12 @@ long Window::wndproc(HWND hwnd, uint msg, WPARAM wparam, LPARAM lparam) {
if(((LPNMLISTVIEW)lparam)->uChanged & LVIF_STATE) {
if(ListView_GetItemState(listbox.hwnd, ((LPNMLISTVIEW)lparam)->iItem, LVIS_FOCUSED)) {
if(ListView_GetItemState(listbox.hwnd, ((LPNMLISTVIEW)lparam)->iItem, LVIS_SELECTED)) {
message(Message::Changed, &control);
message(Message::Changed, (uintptr_t)&control);
}
}
}
} else if(((LPNMHDR)lparam)->code == LVN_ITEMACTIVATE) {
message(Message::DoubleClicked, &control);
message(Message::DoubleClicked, (uintptr_t)&control);
}
} break;
@@ -131,10 +131,14 @@ void Window::attach(Control &control) {
}
void Window::focus() {
show();
if(!visible()) { show(); }
SetFocus(info.hwnd);
}
bool Window::focused() {
return (GetForegroundWindow() == info.hwnd);
}
void Window::move(Control &control, uint x, uint y) {
SetWindowPos(control.hwnd, 0, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
}
@@ -180,6 +184,13 @@ RECT rc;
}
void Window::resize(uint width, uint height) {
if(info.fullscreen == true) {
info.width = GetSystemMetrics(SM_CXSCREEN);
info.height = GetSystemMetrics(SM_CYSCREEN);
SetWindowPos(info.hwnd, 0, 0, 0, info.width, info.height, SWP_NOZORDER);
return;
}
info.width = width;
info.height = height;
@@ -212,6 +223,36 @@ void Window::hide() {
ShowWindow(info.hwnd, SW_HIDE);
}
void Window::show(bool state) {
(state == true) ? show() : hide();
}
bool Window::visible() {
return GetWindowLong(info.hwnd, GWL_STYLE) & WS_VISIBLE;
}
void Window::fullscreen() {
if(info.fullscreen)return;
info.fullscreen = true;
SetWindowLong(info.hwnd, GWL_STYLE, WS_VISIBLE | WS_POPUP);
resize(get_screen_width(), get_screen_height());
}
void Window::unfullscreen() {
if(!info.fullscreen)return;
info.fullscreen = false;
SetWindowLong(info.hwnd, GWL_STYLE, WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX | WS_VISIBLE);
resize(info.width, info.height);
}
void Window::fullscreen(bool state) {
(state == true) ? fullscreen() : unfullscreen();
}
bool Window::is_fullscreen() {
return info.fullscreen;
}
//
void Window::set_text(const char *str, ...) {
@@ -234,6 +275,7 @@ HBRUSH old_brush = info.background;
//
Window::Window() {
info.fullscreen = false;
info.background = 0;
info.center = false;
info.control_index = 1;
+2 -4
View File
@@ -64,10 +64,8 @@
* and speed is less critical.
*****/
#ifndef __LIBVECTOR
#define __LIBVECTOR
#include <new>
#ifndef LIBVECTOR_H
#define LIBVECTOR_H
template<typename T> class linear_vector {
protected:
+8
View File
@@ -27,12 +27,14 @@ IntegerSetting System::speed_fastest (&config_file, "system.speed_fastest", "Fa
struct Video {
static IntegerSetting synchronize;
static IntegerSetting fullscreen;
static IntegerSetting multiplier, aspect_correction, region;
static IntegerSetting hardware_filter, software_filter;
static IntegerSetting frameskip;
static IntegerSetting use_vram;
} video;
IntegerSetting Video::synchronize(&config_file, "video.synchronize", "Synchronize to video refresh rate.", IntegerSetting::Boolean, false);
IntegerSetting Video::fullscreen(0, "video.fullscreen", "", IntegerSetting::Boolean, false);
IntegerSetting Video::multiplier(&config_file, "video.multiplier", "Video output size multiplier (1-5x)\n"
"1 = 1x (~256x224)\n"
"2 = 2x (~512x448)\n"
@@ -124,4 +126,10 @@ StringSetting Input::Joypad2::r (&config_file, "input.joypad2.r", "", "
StringSetting Input::Joypad2::select(&config_file, "input.joypad2.select", "", "lbracket");
StringSetting Input::Joypad2::start (&config_file, "input.joypad2.start", "", "rbracket");
struct Misc {
static IntegerSetting show_frame_counter;
} misc;
IntegerSetting Misc::show_frame_counter(&config_file, "misc.show_frame_counter", "Display frame counter", IntegerSetting::Boolean, true);
};
+1
View File
@@ -8,6 +8,7 @@ class Input { public:
virtual void signal_key_down(uint16 key) {}
virtual void signal_key_up (uint16 key) {}
virtual void clear_input() {}
virtual void poll() {}
virtual void init() {}
virtual void term() {}
+2
View File
@@ -21,6 +21,8 @@ public:
bool key_down(uint16 key) { return keystate[key]; }
void signal_key_down(uint16 key) { keystate[key] = true; }
void signal_key_up (uint16 key) { keystate[key] = false; }
void clear_input() { memset(keystate, 0, sizeof(keystate)); }
};
#endif
+144 -115
View File
@@ -1,115 +1,144 @@
class InputManager { public:
struct Joypad {
uint16 up, down, left, right, a, b, x, y, l, r, select, start;
} joypad1, joypad2;
struct Joystat {
bool up, down, left, right, a, b, x, y, l, r, select, start;
} joystat1, joystat2;
void bind();
void poll();
bool get_status(uint device, uint button);
} input_manager;
void InputManager::bind() {
joypad1.up = keymap::find(config::input.joypad1.up);
joypad1.down = keymap::find(config::input.joypad1.down);
joypad1.left = keymap::find(config::input.joypad1.left);
joypad1.right = keymap::find(config::input.joypad1.right);
joypad1.a = keymap::find(config::input.joypad1.a);
joypad1.b = keymap::find(config::input.joypad1.b);
joypad1.x = keymap::find(config::input.joypad1.x);
joypad1.y = keymap::find(config::input.joypad1.y);
joypad1.l = keymap::find(config::input.joypad1.l);
joypad1.r = keymap::find(config::input.joypad1.r);
joypad1.select = keymap::find(config::input.joypad1.select);
joypad1.start = keymap::find(config::input.joypad1.start);
joystat1.up = joystat1.down = joystat1.left = joystat1.right =
joystat1.a = joystat1.b = joystat1.x = joystat1.y =
joystat1.l = joystat1.r = joystat1.select = joystat1.start = false;
joypad2.up = keymap::find(config::input.joypad2.up);
joypad2.down = keymap::find(config::input.joypad2.down);
joypad2.left = keymap::find(config::input.joypad2.left);
joypad2.right = keymap::find(config::input.joypad2.right);
joypad2.a = keymap::find(config::input.joypad2.a);
joypad2.b = keymap::find(config::input.joypad2.b);
joypad2.x = keymap::find(config::input.joypad2.x);
joypad2.y = keymap::find(config::input.joypad2.y);
joypad2.l = keymap::find(config::input.joypad2.l);
joypad2.r = keymap::find(config::input.joypad2.r);
joypad2.select = keymap::find(config::input.joypad2.select);
joypad2.start = keymap::find(config::input.joypad2.start);
joystat2.up = joystat2.down = joystat2.left = joystat2.right =
joystat2.a = joystat2.b = joystat2.x = joystat2.y =
joystat2.l = joystat2.r = joystat2.select = joystat2.start = false;
}
void InputManager::poll() {
joystat1.up = uiInput->key_down(joypad1.up);
joystat1.down = uiInput->key_down(joypad1.down);
joystat1.left = uiInput->key_down(joypad1.left);
joystat1.right = uiInput->key_down(joypad1.right);
joystat1.a = uiInput->key_down(joypad1.a);
joystat1.b = uiInput->key_down(joypad1.b);
joystat1.x = uiInput->key_down(joypad1.x);
joystat1.y = uiInput->key_down(joypad1.y);
joystat1.l = uiInput->key_down(joypad1.l);
joystat1.r = uiInput->key_down(joypad1.r);
joystat1.select = uiInput->key_down(joypad1.select);
joystat1.start = uiInput->key_down(joypad1.start);
joystat2.up = uiInput->key_down(joypad2.up);
joystat2.down = uiInput->key_down(joypad2.down);
joystat2.left = uiInput->key_down(joypad2.left);
joystat2.right = uiInput->key_down(joypad2.right);
joystat2.a = uiInput->key_down(joypad2.a);
joystat2.b = uiInput->key_down(joypad2.b);
joystat2.x = uiInput->key_down(joypad2.x);
joystat2.y = uiInput->key_down(joypad2.y);
joystat2.l = uiInput->key_down(joypad2.l);
joystat2.r = uiInput->key_down(joypad2.r);
joystat2.select = uiInput->key_down(joypad2.select);
joystat2.start = uiInput->key_down(joypad2.start);
}
bool InputManager::get_status(uint device, uint button) {
switch(device) {
case SNES::DEVICEID_JOYPAD1:
switch(button) {
case SNES::JOYPAD_UP: return joystat1.up;
case SNES::JOYPAD_DOWN: return joystat1.down;
case SNES::JOYPAD_LEFT: return joystat1.left;
case SNES::JOYPAD_RIGHT: return joystat1.right;
case SNES::JOYPAD_A: return joystat1.a;
case SNES::JOYPAD_B: return joystat1.b;
case SNES::JOYPAD_X: return joystat1.x;
case SNES::JOYPAD_Y: return joystat1.y;
case SNES::JOYPAD_L: return joystat1.l;
case SNES::JOYPAD_R: return joystat1.r;
case SNES::JOYPAD_SELECT: return joystat1.select;
case SNES::JOYPAD_START: return joystat1.start;
}
break;
case SNES::DEVICEID_JOYPAD2:
switch(button) {
case SNES::JOYPAD_UP: return joystat2.up;
case SNES::JOYPAD_DOWN: return joystat2.down;
case SNES::JOYPAD_LEFT: return joystat2.left;
case SNES::JOYPAD_RIGHT: return joystat2.right;
case SNES::JOYPAD_A: return joystat2.a;
case SNES::JOYPAD_B: return joystat2.b;
case SNES::JOYPAD_X: return joystat2.x;
case SNES::JOYPAD_Y: return joystat2.y;
case SNES::JOYPAD_L: return joystat2.l;
case SNES::JOYPAD_R: return joystat2.r;
case SNES::JOYPAD_SELECT: return joystat2.select;
case SNES::JOYPAD_START: return joystat2.start;
}
break;
}
return false;
}
class InputManager { public:
struct Joypad {
uint16 up, down, left, right, a, b, x, y, l, r, select, start;
} joypad1, joypad2;
struct Joystat {
bool up, down, left, right, a, b, x, y, l, r, select, start;
} joystat1, joystat2;
uint16 scan();
void bind();
void poll();
bool get_status(uint device, uint button);
} input_manager;
//search all key bindings, return keymap::none if no keys are active
uint16 InputManager::scan() {
uiInput->poll();
for(uint i = 0; i < keymap::limit; i++) {
if(uiInput->key_down(i)) { return i; }
}
for(uint j = 0; j < 16; j++) {
if(uiInput->key_down(keymap::joypad_flag | (j << 16) | keymap::joypad_up)) {
return (keymap::joypad_flag | (j << 16) | keymap::joypad_up);
}
if(uiInput->key_down(keymap::joypad_flag | (j << 16) | keymap::joypad_down)) {
return (keymap::joypad_flag | (j << 16) | keymap::joypad_down);
}
if(uiInput->key_down(keymap::joypad_flag | (j << 16) | keymap::joypad_left)) {
return (keymap::joypad_flag | (j << 16) | keymap::joypad_left);
}
if(uiInput->key_down(keymap::joypad_flag | (j << 16) | keymap::joypad_right)) {
return (keymap::joypad_flag | (j << 16) | keymap::joypad_right);
}
for(uint i = 0; i < 128; i++) {
if(uiInput->key_down(keymap::joypad_flag | (j << 16) | i)) {
return (keymap::joypad_flag | (j << 16) | i);
}
}
}
return keymap::none;
}
void InputManager::bind() {
joypad1.up = keymap::find(config::input.joypad1.up);
joypad1.down = keymap::find(config::input.joypad1.down);
joypad1.left = keymap::find(config::input.joypad1.left);
joypad1.right = keymap::find(config::input.joypad1.right);
joypad1.a = keymap::find(config::input.joypad1.a);
joypad1.b = keymap::find(config::input.joypad1.b);
joypad1.x = keymap::find(config::input.joypad1.x);
joypad1.y = keymap::find(config::input.joypad1.y);
joypad1.l = keymap::find(config::input.joypad1.l);
joypad1.r = keymap::find(config::input.joypad1.r);
joypad1.select = keymap::find(config::input.joypad1.select);
joypad1.start = keymap::find(config::input.joypad1.start);
joystat1.up = joystat1.down = joystat1.left = joystat1.right =
joystat1.a = joystat1.b = joystat1.x = joystat1.y =
joystat1.l = joystat1.r = joystat1.select = joystat1.start = false;
joypad2.up = keymap::find(config::input.joypad2.up);
joypad2.down = keymap::find(config::input.joypad2.down);
joypad2.left = keymap::find(config::input.joypad2.left);
joypad2.right = keymap::find(config::input.joypad2.right);
joypad2.a = keymap::find(config::input.joypad2.a);
joypad2.b = keymap::find(config::input.joypad2.b);
joypad2.x = keymap::find(config::input.joypad2.x);
joypad2.y = keymap::find(config::input.joypad2.y);
joypad2.l = keymap::find(config::input.joypad2.l);
joypad2.r = keymap::find(config::input.joypad2.r);
joypad2.select = keymap::find(config::input.joypad2.select);
joypad2.start = keymap::find(config::input.joypad2.start);
joystat2.up = joystat2.down = joystat2.left = joystat2.right =
joystat2.a = joystat2.b = joystat2.x = joystat2.y =
joystat2.l = joystat2.r = joystat2.select = joystat2.start = false;
}
void InputManager::poll() {
joystat1.up = uiInput->key_down(joypad1.up);
joystat1.down = uiInput->key_down(joypad1.down);
joystat1.left = uiInput->key_down(joypad1.left);
joystat1.right = uiInput->key_down(joypad1.right);
joystat1.a = uiInput->key_down(joypad1.a);
joystat1.b = uiInput->key_down(joypad1.b);
joystat1.x = uiInput->key_down(joypad1.x);
joystat1.y = uiInput->key_down(joypad1.y);
joystat1.l = uiInput->key_down(joypad1.l);
joystat1.r = uiInput->key_down(joypad1.r);
joystat1.select = uiInput->key_down(joypad1.select);
joystat1.start = uiInput->key_down(joypad1.start);
joystat2.up = uiInput->key_down(joypad2.up);
joystat2.down = uiInput->key_down(joypad2.down);
joystat2.left = uiInput->key_down(joypad2.left);
joystat2.right = uiInput->key_down(joypad2.right);
joystat2.a = uiInput->key_down(joypad2.a);
joystat2.b = uiInput->key_down(joypad2.b);
joystat2.x = uiInput->key_down(joypad2.x);
joystat2.y = uiInput->key_down(joypad2.y);
joystat2.l = uiInput->key_down(joypad2.l);
joystat2.r = uiInput->key_down(joypad2.r);
joystat2.select = uiInput->key_down(joypad2.select);
joystat2.start = uiInput->key_down(joypad2.start);
}
bool InputManager::get_status(uint device, uint button) {
switch(device) {
case SNES::DEVICEID_JOYPAD1:
switch(button) {
case SNES::JOYPAD_UP: return joystat1.up;
case SNES::JOYPAD_DOWN: return joystat1.down;
case SNES::JOYPAD_LEFT: return joystat1.left;
case SNES::JOYPAD_RIGHT: return joystat1.right;
case SNES::JOYPAD_A: return joystat1.a;
case SNES::JOYPAD_B: return joystat1.b;
case SNES::JOYPAD_X: return joystat1.x;
case SNES::JOYPAD_Y: return joystat1.y;
case SNES::JOYPAD_L: return joystat1.l;
case SNES::JOYPAD_R: return joystat1.r;
case SNES::JOYPAD_SELECT: return joystat1.select;
case SNES::JOYPAD_START: return joystat1.start;
}
break;
case SNES::DEVICEID_JOYPAD2:
switch(button) {
case SNES::JOYPAD_UP: return joystat2.up;
case SNES::JOYPAD_DOWN: return joystat2.down;
case SNES::JOYPAD_LEFT: return joystat2.left;
case SNES::JOYPAD_RIGHT: return joystat2.right;
case SNES::JOYPAD_A: return joystat2.a;
case SNES::JOYPAD_B: return joystat2.b;
case SNES::JOYPAD_X: return joystat2.x;
case SNES::JOYPAD_Y: return joystat2.y;
case SNES::JOYPAD_L: return joystat2.l;
case SNES::JOYPAD_R: return joystat2.r;
case SNES::JOYPAD_SELECT: return joystat2.select;
case SNES::JOYPAD_START: return joystat2.start;
}
break;
}
return false;
}
+45 -16
View File
@@ -1,12 +1,12 @@
namespace event {
void update_frame_counter() {
if(r_ppu->status.frames_updated) {
r_ppu->status.frames_updated = false;
if(bool(true) == true) { //TODO: add config file variable to toggle fps counter
window_main.set_text("%s [%d]", BSNES_TITLE, r_ppu->status.frames_executed);
}
}
namespace event {
void update_frame_counter() {
if(r_ppu->status.frames_updated) {
r_ppu->status.frames_updated = false;
if(config::misc.show_frame_counter == true) {
window_main.set_text(string() << BSNES_TITLE << " [" << r_ppu->status.frames_executed << "]");
}
}
}
void update_video_settings() {
@@ -16,10 +16,25 @@ uint multiplier = minmax<1, 5>(uint(config::video.multiplier));
width *= multiplier;
height *= multiplier;
if(config::video.aspect_correction == true) {
width = uint( double(width) * 8.0 / 7.0 );
if(config::video.region == 0) {
width = uint( double(width) * 8.0 / 7.0 ); //NTSC
} else {
width = uint( double(width) * 48.0 / 35.0 ); //PAL
}
}
if(config::video.fullscreen) {
//window_main.menu.hide();
window_main.fullscreen();
window_main.view.move((ui::get_screen_width() - width) / 2, (ui::get_screen_height() - height) / 2);
window_main.view.resize(width, height);
} else {
//window_main.menu.show();
window_main.unfullscreen();
window_main.resize(width, height);
window_main.view.move(0, 0);
window_main.view.resize(width, height);
}
window_main.resize(width, height);
window_main.view.resize(width, height);
}
void update_raster_settings() {
@@ -40,6 +55,16 @@ uint filter, standard;
snes.set_video_standard(standard);
}
void toggle_menu() {
window_main.menu.show(!window_main.menu.visible());
update_video_settings();
}
void toggle_fullscreen() {
config::video.fullscreen = !config::video.fullscreen;
update_video_settings();
}
//
bool load_rom(char *fn) {
@@ -57,7 +82,7 @@ stringarray dir;
strcat(dir[0], dir[1]);
}
return ui::file_load(window_main, fn,
return ui::file_load(&window_main, fn,
"SNES images;*.smc,*.sfc,*.swc,*.fig,*.ufo,*.gd3,*.078,*.st"
#if defined(GZIP_SUPPORT)
",*.gz,*.z,*.zip"
@@ -70,7 +95,7 @@ stringarray dir;
}
void load_rom() {
char fn[4096];
char fn[PATH_MAX];
if(load_rom(fn) == false)return;
if(cartridge.loaded() == true)cartridge.unload();
@@ -81,8 +106,12 @@ char fn[4096];
}
void unload_rom() {
cartridge.unload();
uiAudio->clear_audio();
if(cartridge.loaded() == true) {
cartridge.unload();
uiVideo->clear_video();
uiAudio->clear_audio();
}
window_main.set_text(BSNES_TITLE);
}
void reset() {
+3 -1
View File
@@ -1,8 +1,10 @@
namespace event {
void update_frame_counter();
void update_video_settings();
void update_raster_settings();
void toggle_menu();
void toggle_fullscreen();
bool load_rom(char *fn);
void load_rom();
+20 -32
View File
@@ -1,3 +1,5 @@
void run();
#if defined(PLATFORM_WIN)
#include "../../lib/libui_win.h"
#elif defined(PLATFORM_X)
@@ -43,31 +45,6 @@ va_list args;
fprintf(stdout, "[%d]: %s\r\n", source, str);
}
#if 0
void set_config_filename(const char *filename) {
realpath(filename, config::filename);
//if argv[0] does not contain path information, obtain from getcwd()
//otherwise, it was retrieved from argv[0] + realpath()
if(strchr(config::filename, '/') == 0 && strchr(config::filename, '\\') == 0) {
getcwd(config::filename, PATH_MAX);
strcat(config::filename, "/");
}
//convert all path delimiters to '/'
for(int i = 0; i < strlen(config::filename); i++) {
if(config::filename[i] == '\\') { config::filename[i] = '/'; }
}
//remove program name from filename
char *p = strrchr(config::filename, '/');
if(p) { *p = 0; }
//finally, append config file name
strcat(config::filename, "/bsnes.cfg");
}
#endif
void set_config_filename() {
userpath(config::filename);
strcat(config::filename, "/.bsnes");
@@ -75,6 +52,14 @@ void set_config_filename() {
strcat(config::filename, "/bsnes.cfg");
}
void run() {
while(ui::events_pending() == true) { ui::run(); }
if(cartridge.loaded() == true) {
snes.runtoframe();
event::update_frame_counter();
}
}
#if defined(PLATFORM_WIN)
int __stdcall WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) {
int argc = __argc;
@@ -92,15 +77,18 @@ int main(int argc, char *argv[]) {
init_snes();
ui_init();
while(_term_ == false) {
while(ui::events_pending() == true) { ui::run(); }
if(cartridge.loaded() == true) {
snes.runtoframe();
event::update_frame_counter();
}
if(argc >= 2) {
cartridge.load_begin(Cartridge::CART_NORMAL);
cartridge.load(argv[1]);
cartridge.load_end();
snes.power();
}
if(cartridge.loaded() == true) { cartridge.unload(); }
while(_term_ == false) {
run();
}
event::unload_rom();
config_file.save(config::filename);
term_snes();
+9 -8
View File
@@ -1,23 +1,24 @@
int AdvancedWindow::message(uint id, void *param) {
if(id == ui::Message::Changed && param == &list) {
bool AdvancedWindow::message(uint id, uintptr_t param) {
ui::Control *control = (ui::Control*)param;
if(id == ui::Message::Changed && control == &list) {
int pos = list.get_selection();
set_val.enable(pos >= 0);
set_def.enable(pos >= 0);
if(pos >= 0 && pos < config_file.list_count) {
desc.set_text("(default = %s)\n%s", config_file.list[pos]->def, config_file.list[pos]->desc);
desc.set_text(string() << "(default = " << config_file.list[pos]->def << ")\n" << config_file.list[pos]->desc);
string val;
config_file.list[pos]->get(val);
edit_val.set_text("%s", strptr(val));
edit_val.set_text(strptr(val));
}
} else if(id == ui::Message::Clicked && param == &set_val) {
} else if(id == ui::Message::Clicked && control == &set_val) {
char t[4096];
edit_val.get_text(t, sizeof(t));
update(list.get_selection(), t);
} else if(id == ui::Message::Clicked && param == &set_def) {
} else if(id == ui::Message::Clicked && control == &set_def) {
update(list.get_selection(), 0);
}
return 0;
return true;
}
void AdvancedWindow::read_config(uint pos, string &data) {
@@ -39,7 +40,7 @@ void AdvancedWindow::update(uint pos, const char *data) {
config_file.list[pos]->set(data ? data : config_file.list[pos]->def);
string val;
config_file.list[pos]->get(val);
edit_val.set_text("%s", strptr(val));
edit_val.set_text(strptr(val));
read_config(pos, val);
list.set_item(pos, strptr(val));
list.autosize_columns();
+1 -1
View File
@@ -4,7 +4,7 @@ ui::Editbox desc;
ui::Editbox edit_val;
ui::Button set_val;
ui::Button set_def;
int message(uint id, void *param);
bool message(uint id, uintptr_t param);
void read_config(uint pos, string &data);
void update(uint pos, const char *data);
void setup();
+2 -2
View File
@@ -1,5 +1,5 @@
int CheatEditorWindow::message(uint id, void *param) {
return 0;
bool CheatEditorWindow::message(uint id, uintptr_t param) {
return true;
}
void CheatEditorWindow::setup() {
+1 -1
View File
@@ -5,6 +5,6 @@ ui::Button toggle_code;
ui::Button delete_code;
ui::Editbox code;
ui::Editbox desc;
int message(uint id, void *param);
bool message(uint id, uintptr_t param);
void setup();
} window_cheat_editor;
+72 -22
View File
@@ -58,7 +58,7 @@ uint InputConfigWindow::get_value(uint index) {
return keymap::none;
}
void InputConfigWindow::set_value(uint index, uint value) {
void InputConfigWindow::set_value(uint index, uint16 value) {
switch(index) {
case 0: config::input.joypad1.up = keymap::find(value); break;
case 1: config::input.joypad1.down = keymap::find(value); break;
@@ -92,47 +92,65 @@ void InputConfigWindow::set_value(uint index, uint value) {
void InputConfigWindow::refresh_list() {
for(uint i = 0; i < 24; i++) {
list.set_item(i, "%s|%s", list_index[i], keymap::find(get_value(i)));
list.set_item(i, string() << list_index[i] << "|" << keymap::find(get_value(i)));
}
list.autosize_columns();
}
int InputConfigWindow::message(uint id, void *param) {
if(id == ui::Message::Changed && param == &list) {
bool InputConfigWindow::message(uint id, uintptr_t param) {
ui::Control *control = (ui::Control*)param;
if(id == ui::Message::KeyDown) {
if(uiInput) { uiInput->signal_key_down(param); }
return true;
}
if(id == ui::Message::KeyUp) {
if(uiInput) { uiInput->signal_key_up(param); }
return true;
}
if(id == ui::Message::Changed && control == &list) {
int pos = list.get_selection();
setkey.enable(pos >= 0);
clrkey.enable(pos >= 0);
} else if((id == ui::Message::DoubleClicked && param == &list) ||
(id == ui::Message::Clicked && param == &setkey)) {
return true;
}
if((id == ui::Message::DoubleClicked && control == &list) ||
(id == ui::Message::Clicked && control == &setkey)) {
int pos = list.get_selection();
if(pos < 0) { return 0; }
if(pos < 0) { return true; }
window_input_capture.index = pos;
window_input_capture.label.set_text("Please press a key to assign to '%s' ...", list_index[pos]);
window_input_capture.label.set_text(string() << "Please press a key to assign to " << list_index[pos] << " ...");
window_input_capture.show();
window_input_capture.focus();
} else if(id == ui::Message::Clicked && param == &clrkey) {
return true;
}
if(id == ui::Message::Clicked && control == &clrkey) {
int pos = list.get_selection();
if(pos < 0) { return 0; }
if(pos < 0) { return true; }
set_value(pos, keymap::none);
refresh_list();
return true;
}
return 0;
return true;
}
void InputConfigWindow::setup() {
create(0, 475, 355);
int x = 0, y = 0;
lportA.create(*this, 0, x, y + 7, 105, 15, "Controller Port A:");
portA.create(*this, 0, x + 110, y, 125, 30);
lportA.create(*this, 0, x, y, 105, 30, "Controller Port A:");
portA.create (*this, 0, x + 110, y, 125, 30);
portA.add_item("None");
portA.add_item("Joypad 1");
portA.add_item("Joypad 2");
portA.set_selection(1);
portA.disable();
lportB.create(*this, 0, x + 240, y + 7, 105, 15, "Controller Port B:");
portB.create(*this, 0, x + 350, y, 125, 30);
lportB.create(*this, 0, x + 240, y, 105, 30, "Controller Port B:");
portB.create (*this, 0, x + 350, y, 125, 30);
portB.add_item("None");
portB.add_item("Joypad 1");
portB.add_item("Joypad 2");
@@ -156,16 +174,48 @@ int x = 0, y = 0;
//
int InputCaptureWindow::message(uint id, void *param) {
bool InputCaptureWindow::message(uint id, uintptr_t param) {
if(id == ui::Message::Close) {
hide();
return false;
} else if(id == ui::Message::KeyUp) {
hide();
window_input_config.set_value(index, uint(param));
window_input_config.refresh_list();
}
return 0;
if(id == ui::Message::KeyDown) {
if(uiInput) { uiInput->signal_key_down(param); }
return true;
}
if(id == ui::Message::KeyUp) {
if(uiInput) { uiInput->signal_key_up(param); }
return true;
}
return true;
}
void InputCaptureWindow::show() {
uiInput->clear_input();
//enter and spacebar can be used to activate key capture,
//set lock on these keys if they are held down to prevent
//them from being instantly assigned to selected entry ...
uiInput->poll();
key_lock = (uiInput->key_down(keymap::enter) || uiInput->key_down(keymap::space));
Window::show();
Window::focus();
while(_term_ == false && visible() == true) {
run();
uint16 key = input_manager.scan();
if(key == keymap::none) { key_lock = false; continue; }
if(key_lock && (key == keymap::enter || key == keymap::space)) { continue; }
hide();
window_input_config.set_value(index, key);
window_input_config.refresh_list();
break;
}
uiInput->clear_input();
}
void InputCaptureWindow::setup() {
+5 -3
View File
@@ -1,7 +1,9 @@
class InputCaptureWindow : public ui::Window { public:
ui::Label label;
uint index;
int message(uint id, void *param = 0);
bool key_lock;
bool message(uint id, uintptr_t param = 0);
void show();
void setup();
InputCaptureWindow() : index(0) {}
} window_input_capture;
@@ -17,9 +19,9 @@ ui::Button clrkey;
static const char list_index[][64];
int message(uint id, void *param = 0);
bool message(uint id, uintptr_t param = 0);
uint get_value(uint index);
void set_value(uint index, uint value);
void set_value(uint index, uint16 value);
void refresh_list();
void setup();
} window_input_config;
+26 -25
View File
@@ -1,49 +1,50 @@
int RasterSettingsWindow::message(uint id, void *param) {
bool RasterSettingsWindow::message(uint id, uintptr_t param) {
ui::Control *control = (ui::Control*)param;
if(id == ui::Message::Changed) {
if(param == &contrast) {
if(control == &contrast) {
if(config::snes.contrast != contrast.get_position() - 96) {
config::snes.contrast = contrast.get_position() - 96;
lcontrast.set_text("Contrast: %d", int(config::snes.contrast));
lcontrast.set_text(string() << "Contrast: " << config::snes.contrast);
snes.update_color_lookup_table();
}
} else if(param == &brightness) {
} else if(control == &brightness) {
if(config::snes.brightness != brightness.get_position() - 96) {
config::snes.brightness = brightness.get_position() - 96;
lbrightness.set_text("Brightness: %d", int(config::snes.brightness));
lbrightness.set_text(string() << "Brightness: " << config::snes.brightness);
snes.update_color_lookup_table();
}
} else if(param == &gamma) {
} else if(control == &gamma) {
if(config::snes.gamma != gamma.get_position() + 10) {
config::snes.gamma = gamma.get_position() + 10;
lgamma.set_text("Gamma: %0.2f", double(config::snes.gamma) / 100.0);
lgamma.set_text(string() << "Gamma: " << config::snes.gamma); //TODO: print gamma as "%0.2f" / 100.0
snes.update_color_lookup_table();
}
}
return 0;
return true;
}
if(id == ui::Message::Clicked) {
if(param == &gamma_ramp) {
if(control == &gamma_ramp) {
if(config::snes.gamma_ramp != gamma_ramp.checked()) {
config::snes.gamma_ramp = gamma_ramp.checked();
snes.update_color_lookup_table();
}
} else if(param == &sepia) {
} else if(control == &sepia) {
if(config::snes.sepia != sepia.checked()) {
config::snes.sepia = sepia.checked();
snes.update_color_lookup_table();
}
} else if(param == &grayscale) {
} else if(control == &grayscale) {
if(config::snes.grayscale != grayscale.checked()) {
config::snes.grayscale = grayscale.checked();
snes.update_color_lookup_table();
}
} else if(param == &invert) {
} else if(control == &invert) {
if(config::snes.invert != invert.checked()) {
config::snes.invert = invert.checked();
snes.update_color_lookup_table();
}
} else if(param == &preset_optimal) {
} else if(control == &preset_optimal) {
config::snes.contrast = 0;
config::snes.brightness = 0;
config::snes.gamma = 80;
@@ -52,7 +53,7 @@ int RasterSettingsWindow::message(uint id, void *param) {
config::snes.grayscale = false;
config::snes.invert = false;
sync_ui();
} else if(param == &preset_standard) {
} else if(control == &preset_standard) {
config::snes.contrast = 0;
config::snes.brightness = 0;
config::snes.gamma = 100;
@@ -62,20 +63,20 @@ int RasterSettingsWindow::message(uint id, void *param) {
config::snes.invert = false;
sync_ui();
}
return 0;
return true;
}
return 0;
return true;
}
//update all UI controls to match config file values ...
void RasterSettingsWindow::sync_ui() {
contrast.set_position(config::snes.contrast + 96);
lcontrast.set_text("Contrast: %d", int(config::snes.contrast));
lcontrast.set_text(string() << "Contrast: " << config::snes.contrast);
brightness.set_position(config::snes.brightness + 96);
lbrightness.set_text("Brightness: %d", int(config::snes.brightness));
lbrightness.set_text(string() << "Brightness: " << config::snes.brightness);
gamma.set_position(config::snes.gamma - 10);
lgamma.set_text("Gamma: %0.2f", double(config::snes.gamma) / 100.0);
lgamma.set_text(string() << "Gamma: " << config::snes.gamma); //TODO: print gamma as "%0.2f" / 100.0
gamma_ramp.check(config::snes.gamma_ramp);
sepia.check(config::snes.sepia);
grayscale.check(config::snes.grayscale);
@@ -87,16 +88,16 @@ void RasterSettingsWindow::setup() {
create(0, 475, 355);
int x = 0, y = 0;
lcontrast.create(*this, 0, x, y + 5, 100, 15);
contrast.create(*this, 0, x + 100, y, 375, 25, 192);
lcontrast.create(*this, 0, x, y, 100, 25);
contrast.create (*this, 0, x + 100, y, 375, 25, 192);
y += 25;
lbrightness.create(*this, 0, x, y + 5, 100, 15);
brightness.create(*this, 0, x + 100, y, 375, 25, 192);
lbrightness.create(*this, 0, x, y, 100, 25);
brightness.create (*this, 0, x + 100, y, 375, 25, 192);
y += 25;
lgamma.create(*this, 0, x, y + 5, 100, 15);
gamma.create(*this, 0, x + 100, y, 375, 25, 191);
lgamma.create(*this, 0, x, y, 100, 25);
gamma.create (*this, 0, x + 100, y, 375, 25, 191);
y += 25;
gamma_ramp.create(*this, 0, x, y, 235, 20, "Gamma ramp");
+1 -1
View File
@@ -14,7 +14,7 @@ ui::Checkbox invert;
ui::Button preset_optimal;
ui::Button preset_standard;
int message(uint id, void *param);
bool message(uint id, uintptr_t param);
void setup();
void sync_ui();
} window_raster_settings;
+7 -7
View File
@@ -3,7 +3,7 @@ void SettingsWindow::setup() {
panel_list.create(*this, 0, 5, 5, 150, 355);
panel_list.add_item("Raster Settings");
panel_list.add_item("Input Configuration");
//panel_list.add_item("Cheat Code Editor");
panel_list.add_item("Cheat Code Editor");
panel_list.add_item("Advanced");
panel.create(*this, 0, 160, 5, 475, 355);
@@ -15,22 +15,22 @@ void SettingsWindow::show() {
panel_list.focus();
}
int SettingsWindow::message(uint id, void *param) {
bool SettingsWindow::message(uint id, uintptr_t param) {
if(id == ui::Message::Close) {
hide();
return false;
}
if(id == ui::Message::Changed && param == &panel_list) {
if(id == ui::Message::Changed && (ui::Control*)param == &panel_list) {
switch(panel_list.get_selection()) {
case 0: panel.attach(window_raster_settings); break;
case 1: panel.attach(window_input_config); break;
//case 2: panel.attach(window_cheat_editor); break;
case 2: panel.attach(window_advanced); break;
case 2: panel.attach(window_cheat_editor); break;
case 3: panel.attach(window_advanced); break;
}
panel_list.focus();
return 0;
return true;
}
return 0;
return true;
}
+1 -1
View File
@@ -1,7 +1,7 @@
class SettingsWindow : public ui::Window { public:
ui::Listbox panel_list;
ui::Panel panel;
int message(uint id, void *param);
bool message(uint id, uintptr_t param = 0);
void show();
void setup();
} window_settings;
+2 -2
View File
@@ -13,11 +13,11 @@ void AboutWindow::setup() {
about.create(*this, 0, 5, 5, 290, 120, about_text);
}
int AboutWindow::message(uint id, void *param) {
bool AboutWindow::message(uint id, uintptr_t param) {
if(id == ui::Message::Close) {
hide();
return false;
}
return 0;
return true;
}
+1 -1
View File
@@ -1,6 +1,6 @@
class AboutWindow : public ui::Window { public:
ui::Label about;
static const char about_text[4096];
int message(uint id, void *param);
bool message(uint id, uintptr_t param);
void setup();
} window_about;
+50 -46
View File
@@ -1,4 +1,5 @@
int MainWindow::message(uint id, void *param) {
bool MainWindow::message(uint id, uintptr_t param) {
ui::Control *control = (ui::Control*)param;
if(id == ui::Message::Close) {
_term_ = true;
hide();
@@ -7,100 +8,103 @@ int MainWindow::message(uint id, void *param) {
if(id == ui::Message::Block) {
if(uiAudio) { uiAudio->clear_audio(); }
return true;
}
if(id == ui::Message::KeyDown) {
if(uiInput) { uiInput->signal_key_down((int)param); }
return 0;
if(uiInput) { uiInput->signal_key_down(param); }
if(param == keymap::esc) { event::toggle_menu(); }
if(param == keymap::f11) { event::toggle_fullscreen(); }
return true;
}
if(id == ui::Message::KeyUp) {
if(uiInput) { uiInput->signal_key_up((int)param); }
return 0;
if(uiInput) { uiInput->signal_key_up(param); }
return true;
}
if(id == ui::Message::Clicked) {
if(param == &menu_file_load) {
if(control == &menu_file_load) {
event::load_rom();
}
if(param == &menu_file_unload) {
if(control == &menu_file_unload) {
event::unload_rom();
}
if(param == &menu_file_reset) {
if(control == &menu_file_reset) {
event::reset();
}
if(param == &menu_file_power) {
if(control == &menu_file_power) {
event::power();
}
if(param == &menu_file_exit) {
if(control == &menu_file_exit) {
message(ui::Message::Close);
}
if(param == &menu_settings_videomode_1x) { config::video.multiplier = 1; event::update_video_settings(); }
if(param == &menu_settings_videomode_2x) { config::video.multiplier = 2; event::update_video_settings(); }
if(param == &menu_settings_videomode_3x) { config::video.multiplier = 3; event::update_video_settings(); }
if(param == &menu_settings_videomode_4x) { config::video.multiplier = 4; event::update_video_settings(); }
if(param == &menu_settings_videomode_5x) { config::video.multiplier = 5; event::update_video_settings(); }
if(control == &menu_settings_videomode_1x) { config::video.multiplier = 1; event::update_video_settings(); }
if(control == &menu_settings_videomode_2x) { config::video.multiplier = 2; event::update_video_settings(); }
if(control == &menu_settings_videomode_3x) { config::video.multiplier = 3; event::update_video_settings(); }
if(control == &menu_settings_videomode_4x) { config::video.multiplier = 4; event::update_video_settings(); }
if(control == &menu_settings_videomode_5x) { config::video.multiplier = 5; event::update_video_settings(); }
if(param == &menu_settings_videomode_aspect_correction) {
if(control == &menu_settings_videomode_aspect_correction) {
config::video.aspect_correction = menu_settings_videomode_aspect_correction.checked();
event::update_video_settings();
}
if(param == &menu_settings_videomode_ntsc) { config::video.region = 0; event::update_raster_settings(); event::update_video_settings(); }
if(param == &menu_settings_videomode_pal) { config::video.region = 1; event::update_raster_settings(); event::update_video_settings(); }
if(control == &menu_settings_videomode_ntsc) { config::video.region = 0; event::update_raster_settings(); event::update_video_settings(); }
if(control == &menu_settings_videomode_pal) { config::video.region = 1; event::update_raster_settings(); event::update_video_settings(); }
if(param == &menu_settings_videofilter_hwpoint) { config::video.hardware_filter = 0; uiVideo->update_hardware_filter(); }
if(param == &menu_settings_videofilter_hwlinear) { config::video.hardware_filter = 1; uiVideo->update_hardware_filter(); }
if(control == &menu_settings_videofilter_hwpoint) { config::video.hardware_filter = 0; uiVideo->update_hardware_filter(); }
if(control == &menu_settings_videofilter_hwlinear) { config::video.hardware_filter = 1; uiVideo->update_hardware_filter(); }
if(param == &menu_settings_videofilter_swnone) { config::video.software_filter = 0; event::update_raster_settings(); }
if(param == &menu_settings_videofilter_swntsc) { config::video.software_filter = 1; event::update_raster_settings(); }
if(param == &menu_settings_videofilter_swhq2x) { config::video.software_filter = 2; event::update_raster_settings(); }
if(param == &menu_settings_videofilter_swscale2x) { config::video.software_filter = 3; event::update_raster_settings(); }
if(control == &menu_settings_videofilter_swnone) { config::video.software_filter = 0; event::update_raster_settings(); }
if(control == &menu_settings_videofilter_swntsc) { config::video.software_filter = 1; event::update_raster_settings(); }
if(control == &menu_settings_videofilter_swhq2x) { config::video.software_filter = 2; event::update_raster_settings(); }
if(control == &menu_settings_videofilter_swscale2x) { config::video.software_filter = 3; event::update_raster_settings(); }
if(param == &menu_settings_videoframeskip_0) { config::video.frameskip = 0; }
if(param == &menu_settings_videoframeskip_1) { config::video.frameskip = 1; }
if(param == &menu_settings_videoframeskip_2) { config::video.frameskip = 2; }
if(param == &menu_settings_videoframeskip_3) { config::video.frameskip = 3; }
if(param == &menu_settings_videoframeskip_4) { config::video.frameskip = 4; }
if(param == &menu_settings_videoframeskip_5) { config::video.frameskip = 5; }
if(param == &menu_settings_videoframeskip_6) { config::video.frameskip = 6; }
if(param == &menu_settings_videoframeskip_7) { config::video.frameskip = 7; }
if(param == &menu_settings_videoframeskip_8) { config::video.frameskip = 8; }
if(param == &menu_settings_videoframeskip_9) { config::video.frameskip = 9; }
if(control == &menu_settings_videoframeskip_0) { config::video.frameskip = 0; }
if(control == &menu_settings_videoframeskip_1) { config::video.frameskip = 1; }
if(control == &menu_settings_videoframeskip_2) { config::video.frameskip = 2; }
if(control == &menu_settings_videoframeskip_3) { config::video.frameskip = 3; }
if(control == &menu_settings_videoframeskip_4) { config::video.frameskip = 4; }
if(control == &menu_settings_videoframeskip_5) { config::video.frameskip = 5; }
if(control == &menu_settings_videoframeskip_6) { config::video.frameskip = 6; }
if(control == &menu_settings_videoframeskip_7) { config::video.frameskip = 7; }
if(control == &menu_settings_videoframeskip_8) { config::video.frameskip = 8; }
if(control == &menu_settings_videoframeskip_9) { config::video.frameskip = 9; }
if(param == &menu_settings_mute) {
if(control == &menu_settings_mute) {
config::snes.mute = menu_settings_mute.checked();
}
if(param == &menu_settings_speedreg_enable) {
if(control == &menu_settings_speedreg_enable) {
config::system.regulate_speed = menu_settings_speedreg_enable.checked();
}
if(param == &menu_settings_speedreg_slowest) { config::system.speed = 1; uiAudio->update_frequency(); }
if(param == &menu_settings_speedreg_slow) { config::system.speed = 2; uiAudio->update_frequency(); }
if(param == &menu_settings_speedreg_normal) { config::system.speed = 3; uiAudio->update_frequency(); }
if(param == &menu_settings_speedreg_fast) { config::system.speed = 4; uiAudio->update_frequency(); }
if(param == &menu_settings_speedreg_fastest) { config::system.speed = 5; uiAudio->update_frequency(); }
if(control == &menu_settings_speedreg_slowest) { config::system.speed = 1; uiAudio->update_frequency(); }
if(control == &menu_settings_speedreg_slow) { config::system.speed = 2; uiAudio->update_frequency(); }
if(control == &menu_settings_speedreg_normal) { config::system.speed = 3; uiAudio->update_frequency(); }
if(control == &menu_settings_speedreg_fast) { config::system.speed = 4; uiAudio->update_frequency(); }
if(control == &menu_settings_speedreg_fastest) { config::system.speed = 5; uiAudio->update_frequency(); }
if(param == &menu_settings_config) { window_settings.show(); }
if(control == &menu_settings_config) { window_settings.show(); }
if(param == &menu_misc_logaudio) {
if(control == &menu_misc_logaudio) {
(menu_misc_logaudio.checked() == true) ? snes.log_audio_enable() : snes.log_audio_disable();
}
if(param == &menu_misc_about) {
if(control == &menu_misc_about) {
window_about.focus();
}
return 0;
return true;
}
return 0;
return true;
}
void MainWindow::setup() {
+1 -1
View File
@@ -60,7 +60,7 @@ ui::MenuGroup menu_misc;
ui::Container view;
//
int message(uint id, void *param = 0);
bool message(uint id, uintptr_t param = 0);
void setup();
void setup_menu();
} window_main;
+12
View File
@@ -9,6 +9,13 @@ bool VideoXv::lock(uint16 *&data, uint &pitch) {
void VideoXv::unlock() {
}
void VideoXv::clear_video() {
memset(buffer, 0, 1024 * 1024 * sizeof(uint16));
//clear twice in case video is double buffered ...
refresh(1024, 1024);
refresh(1024, 1024);
}
void VideoXv::refresh(uint r_width, uint r_height) {
Window dw;
int d0, d1;
@@ -109,6 +116,10 @@ unsigned int adaptor_count;
XvFreeAdaptorInfo(adaptor_info);
if(xv_port == -1) { printf("VideoXv: failed to find valid XvPort.\n"); }
//set colorkey to auto paint, so that Xv video output is always visible
const Atom atom = XInternAtom(display, "XV_AUTOPAINT_COLORKEY", true);
if(atom != None) { XvSetPortAttribute(display, xv_port, atom, 1); }
//0x00000003 = 32-bit X8R8G8B8 [xRGB] (few drivers support this mode)
//0x32595559 = 16-bit Y8U8,Y8V8 [YUY2] (most drivers support this mode)
xvimage = XvShmCreateImage(display, xv_port, 0x32595559, 0, 1024, 1024, &shminfo);
@@ -119,6 +130,7 @@ unsigned int adaptor_count;
if(!XShmAttach(display, &shminfo)) { printf("VideoXv: XShmAttach failed.\n"); }
init_yuv_tables();
clear_video();
}
VideoXv::~VideoXv() {
+1
View File
@@ -28,6 +28,7 @@ public:
uint screen_width() { return gdk_screen_width(); }
uint screen_height() { return gdk_screen_height(); }
void clear_video();
void refresh(uint width, uint height);
void init();
void term();