sync to dosbox svn, improve osk

This commit is contained in:
dborth 2010-06-24 18:33:09 +00:00
parent e8b2d18eba
commit 92777ffeee
78 changed files with 3270 additions and 3449 deletions

View File

@ -7,5 +7,6 @@ Ulf Wohlers <finsterr>
Tommy Frössman <fanskapet>
Dean Beeler <canadacow>
Sebastian Strohhäcker <c2woody>
Ralf Grillenberger <h-a-l-9000>
nick_without_<> @ users.sourceforge.net

View File

@ -1,67 +1,80 @@
0.74
- Several small game specific fixes/hacks/support. (Offensive,
Roadhog, GTA installer, Kingdom O' Magic soundcard detection,
Pirate booter, armored fist installer)
- Add the S3-specific 640x480 256 color mode. Fixes regression in "Wooden
Ships and Iron Men" and "I Have No Mouth And I Must Scream".
Pirate booter, Armored Fist installer)
- Add the S3-specific 640x480 256 color mode. (fixes regression in "Wooden
Ships and Iron Men" and "I Have No Mouth And I Must Scream")
- Fix a stack overflow that could crash DOSBox.
- Add fake microphone input. (Fixes Talking Parrot)
- Add fake microphone input. (fixes Talking Parrot)
- Modify adlib turn off code, so that it doesn't turn off in
cases where the same sound is repeated over and over again.
- Several small fixes to the CDROM audio code. (HOMM2, Redneck
Rampage and others)
- Several improvements to the CDROM emulation code. (fixes Alpha
Storm and GT Racing 97)
- Some small cpu fixes that might fix something.
- Handle opcode 0xff subcode 7 as invalid instruction, fixes dif-2 & others.
- Some hercules fixes (Testdrive)
- Some small CPU fixes that might fix something.
- Handle opcode 0xff subcode 7 as invalid instruction. (fixes dif-2 & others)
- Some hercules fixes. (Testdrive)
- Improve support for blanked parts that wrap around to the start of
the screen. (Fixes Magic Circle demo and Sid&Al)
- Remove old opl cores as the new ones seem work very nice.
the screen. (fixes Magic Circle demo and Sid&Al)
- Remove old OPL cores as the new ones seem to work very nicely.
- Modify movie recording code so that the movies aren't corrupt when
you exit dosbox without stopping the movie.
- Change RGB3x scaler to look more pretty.
- Improve initial register values compatility of the GUS.
- Change render preferences a bit to be more compatible with windows 7.
- Add DOS fixes to terminate program. (Fixes fortune teller)
- Add FFREEP. (Fixes trucks)
- Improve FPU ST80 in C mode when writing zero. (Fixes antigok)
- Add special int10 scanline function. (Fixes mz700 and probably lots
- Added autodetection for Gameblaster. (games can find it now)
- Change render preferences a bit to be more compatible with Windows 7.
- Add DOS fixes to terminate program. (fixes Fortune Teller)
- Add FFREEP. (fixes Trucks)
- Improve FPU ST80 in C mode when writing zero. (fixes Antigok)
- Add special int10 scanline function. (fixes mz700 and probably lots
of games that mess with them)
- Fix scrolling in rarely used video modes. (Fixes Orphee)
- Fix scrolling in rarely used video modes. (fixes Orphee)
- Modify game specific hacks a bit so that Kick off 3 works again.
- Lots of fixes to the INT10 video parameter table. (Seven spirits
of ra and others)
- Add VGA blanking in machine=vgaonly. (used by Alien Carnage)
- CGA, PCJr, Tandy: Add video blanking, change display start latch
timing, sync pulse width correction.
- PCJr, Tandy: implement vertical retrace interrupt.
- PCJr, CGA: line-by-line video emulation.
- PCJr: support on-screen change of color modes 4medium to 16low. (used
by Ghostbusters booter)
- Hercules: Add green and amber monochrome support.
- All machines: only update the video timing when needed. (Jungle Hunt,
others that synchronize to the video screen might profit)
- Several small DOS fixes.
- Some UMB related fixes. ( The Legacy without umb)
- Some UMB related fixes. (The Legacy without UMB)
- Fix version number of DSP for SB 1.5. (fixes a few games)
- Several vga emulation improvements (Allertone football manager)
- Some tandy fixes. (mech warrior)
- Several VGA emulation improvements. (Allertone football manager)
- Some Tandy fixes. (Mech Warrior)
- Small improvements and fixes to the OPL emulation.
- Add low Level tandy DAC emulation.
- Some EMS fixes. (Fixes Mortal Kombat and others)
- Change SoundBlaster DSP reset mechanism, add sb irq acknowledge logic
(fixes stmik-based applications).
- Some interrupt pointer location modifications. (fixes tinker tales)
- Some fixes to the BOOT code. (fixes last mission)
- Respect write-only. (fixes champions of zulala)
- Some RTC fix. (Fixes Tully Bodine and others)
- Add low level Tandy DAC emulation.
- Some EMS fixes. (fixes Mortal Kombat and others)
- Change SoundBlaster DSP reset mechanism, add sb irq acknowledge logic.
(fixes stmik-based applications)
- Some interrupt pointer location modifications. (fixes Tinker Tales)
- Some fixes to the BOOT code. (fixes Last Mission)
- Respect write-only file information. (fixes Champions of Zulala)
- Some RTC fix. (fixes Tully Bodine and others)
- Improve mouse emulation to work better with Water World.
- Hopefully fix the translation of the configuration file.
- Speed up and fixes for the recompiler core. (pitfall2 pcjr)
- Change memory start location. (Fixes 7th Guest installer)
- Several fixes to the BAT files handling. (Shift and
- Change memory start location. (fixes 7th Guest installer)
- Several fixes to the batch file handling. (Shift and
use the typed first %0 instead of the parsed %0)
- Improve file redirection and redirected line ends. (Fixes
- Improve file redirection and redirected line ends. (fixes
Phantasmagoria 2 DOS installer)
- Fix compilation with new MAC os X version.
- Add 16C550A FIFO support to the serial port emulation.
- Improve modem emulation to get higher speeds.
- Change default samplerates to 44100, so that hopefully certain
soundcards produce more fluent sound playback.
- Change default samplerates to 44100, blocksize to 1024 and prebuffer to 20,
so that hopefully certain soundcards produce more fluent sound playback.
- Add some rarely used, but for some games critical flags to
the internal commands.
- Improve internal timing with repeatings timers (especially with
- Add -userconf flag, so that the userspecific configuration can
easily be used together with -conf configfile.
- Improve internal timing with repeating timers (especially with
the dynamic core).
0.73

79
NEWS
View File

@ -1,3 +1,82 @@
0.74
- Several small game specific fixes/hacks/support. (Offensive,
Roadhog, GTA installer, Kingdom O' Magic soundcard detection,
Pirate booter, Armored Fist installer)
- Add the S3-specific 640x480 256 color mode. (fixes regression in "Wooden
Ships and Iron Men" and "I Have No Mouth And I Must Scream")
- Fix a stack overflow that could crash DOSBox.
- Add fake microphone input. (fixes Talking Parrot)
- Modify adlib turn off code, so that it doesn't turn off in
cases where the same sound is repeated over and over again.
- Several small fixes to the CDROM audio code. (HOMM2, Redneck
Rampage and others)
- Several improvements to the CDROM emulation code. (fixes Alpha
Storm and GT Racing 97)
- Some small CPU fixes that might fix something.
- Handle opcode 0xff subcode 7 as invalid instruction. (fixes dif-2 & others)
- Some hercules fixes. (Testdrive)
- Improve support for blanked parts that wrap around to the start of
the screen. (fixes Magic Circle demo and Sid&Al)
- Remove old OPL cores as the new ones seem to work very nicely.
- Modify movie recording code so that the movies aren't corrupt when
you exit dosbox without stopping the movie.
- Change RGB3x scaler to look more pretty.
- Improve initial register values compatility of the GUS.
- Added autodetection for Gameblaster. (games can find it now)
- Change render preferences a bit to be more compatible with Windows 7.
- Add DOS fixes to terminate program. (fixes Fortune Teller)
- Add FFREEP. (fixes Trucks)
- Improve FPU ST80 in C mode when writing zero. (fixes Antigok)
- Add special int10 scanline function. (fixes mz700 and probably lots
of games that mess with them)
- Fix scrolling in rarely used video modes. (fixes Orphee)
- Modify game specific hacks a bit so that Kick off 3 works again.
- Lots of fixes to the INT10 video parameter table. (Seven spirits
of ra and others)
- Add VGA blanking in machine=vgaonly. (used by Alien Carnage)
- CGA, PCJr, Tandy: Add video blanking, change display start latch
timing, sync pulse width correction.
- PCJr, Tandy: implement vertical retrace interrupt.
- PCJr, CGA: line-by-line video emulation.
- PCJr: support on-screen change of color modes 4medium to 16low. (used
by Ghostbusters booter)
- Hercules: Add green and amber monochrome support.
- All machines: only update the video timing when needed. (Jungle Hunt,
others that synchronize to the video screen might profit)
- Several small DOS fixes.
- Some UMB related fixes. (The Legacy without UMB)
- Fix version number of DSP for SB 1.5. (fixes a few games)
- Several VGA emulation improvements. (Allertone football manager)
- Some Tandy fixes. (Mech Warrior)
- Small improvements and fixes to the OPL emulation.
- Add low level Tandy DAC emulation.
- Some EMS fixes. (fixes Mortal Kombat and others)
- Change SoundBlaster DSP reset mechanism, add sb irq acknowledge logic.
(fixes stmik-based applications)
- Some interrupt pointer location modifications. (fixes Tinker Tales)
- Some fixes to the BOOT code. (fixes Last Mission)
- Respect write-only file information. (fixes Champions of Zulala)
- Some RTC fix. (fixes Tully Bodine and others)
- Improve mouse emulation to work better with Water World.
- Hopefully fix the translation of the configuration file.
- Speed up and fixes for the recompiler core. (pitfall2 pcjr)
- Change memory start location. (fixes 7th Guest installer)
- Several fixes to the batch file handling. (Shift and
use the typed first %0 instead of the parsed %0)
- Improve file redirection and redirected line ends. (fixes
Phantasmagoria 2 DOS installer)
- Fix compilation with new MAC os X version.
- Add 16C550A FIFO support to the serial port emulation.
- Improve modem emulation to get higher speeds.
- Change default samplerates to 44100, blocksize to 1024 and prebuffer to 20,
so that hopefully certain soundcards produce more fluent sound playback.
- Add some rarely used, but for some games critical flags to
the internal commands.
- Add -userconf flag, so that the userspecific configuration can
easily be used together with -conf configfile.
- Improve internal timing with repeating timers (especially with
the dynamic core).
0.73
- Add two new opl2+opl3 emulators. (better speed, different implementation
approach)

1408
README

File diff suppressed because it is too large Load Diff

3
THANKS
View File

@ -7,7 +7,7 @@ Jarek Burczynski for the new OPL3 emulator.
Ken Silverman for his work on an OPL2 emulator.
The Bochs and DOSemu projects which I used for information.
Freedos for ideas in making my shell.
FreeDOS for ideas in making my shell.
Pierre-Yves Gérardy for hosting the old Beta Board.
Colin Snover for hosting our forum.
@ -22,6 +22,7 @@ Jantien for the version management.
Shawn, Johannes and Marcus for creating the MAC OS X version.
Jochen for creating the OS/2 version.
Ido Beeri for the icon.
ripsaw8080 for his hard debugging work.
GOG Team for the splash screen.
All the people who submitted a bug.
The Beta Testers.

View File

@ -1 +1 @@
0.73
0.74

View File

@ -390,9 +390,9 @@ typedef double Real64;
#if SIZEOF_INT_P == 4
typedef Bit32u Bitu;
typedef Bit32s Bits;
#else
#else
typedef Bit64u Bitu;
typedef Bit64s Bits;
#endif
#endif
])

View File

@ -1,11 +1,11 @@
dnl Init.
AC_INIT(dosbox,0.73)
AC_INIT(dosbox,0.74)
AC_PREREQ(2.50)
AC_CONFIG_SRCDIR(README)
dnl Detect the canonical host and target build environment
AC_CANONICAL_HOST
AC_CANONICAL_TARGET
AC_CANONICAL_BUILD
dnl Setup for automake
AM_INIT_AUTOMAKE
@ -21,7 +21,7 @@ AC_PROG_RANLIB
dnl Some needed libaries for OS2
dnl perharps join this with the other target depended checks. move them upwards
if test x$target = xi386-pc-os2-emx ; then
if test x$host = xi386-pc-os2-emx ; then
CXXFLAGS="$CXXFLAGS -Zmt"
LDFLAGS="$LDFLAGS -Zomf -Zmt"
LIBS="$LIBS -los2me"
@ -231,7 +231,7 @@ AC_ARG_ENABLE(core-inline,AC_HELP_STRING([--enable-core-inline],[Enable inlined
dnl The target cpu checks for dynamic cores
AH_TEMPLATE(C_TARGETCPU,[The type of cpu this target has])
AC_MSG_CHECKING(for target cpu type)
case "$target_cpu" in
case "$host_cpu" in
x86_64 | amd64)
AC_DEFINE(C_TARGETCPU,X86_64)
AC_MSG_RESULT(x86-64 bit compatible)
@ -343,7 +343,7 @@ fi
AH_TEMPLATE(C_SSHOT,[Define to 1 to enable screenshots, requires libpng])
AC_CHECK_HEADER(png.h,have_png_h=yes,)
AC_CHECK_LIB(png, png_check_sig, have_png_lib=yes, ,-lz)
AC_CHECK_LIB(png, png_get_io_ptr, have_png_lib=yes, ,-lz)
if test x$have_png_lib = xyes -a x$have_png_h = xyes ; then
LIBS="$LIBS -lpng -lz"
AC_DEFINE(C_SSHOT,1)
@ -355,7 +355,7 @@ AH_TEMPLATE(C_MODEM,[Define to 1 to enable internal modem support, requires SDL_
AH_TEMPLATE(C_IPX,[Define to 1 to enable IPX over Internet networking, requires SDL_net])
AC_CHECK_HEADER(SDL_net.h,have_sdl_net_h=yes,)
if test x$target = xi386-pc-os2-emx ; then
if test x$host = xi386-pc-os2-emx ; then
AC_MSG_CHECKING(for SDLNet_Init in SDL_net);
LIBS_BACKUP=$LIBS;
LIBS="$LIBS -lSDL_Net";
@ -393,7 +393,7 @@ AC_CHECK_HEADER(GL/gl.h, have_gl_h=yes , have_gl_h=no , )
AC_ARG_ENABLE(opengl,AC_HELP_STRING([--disable-opengl],[Disable opengl support]),,enable_opengl=yes)
AC_MSG_CHECKING(whether opengl display output will be enabled)
if test x$enable_opengl = xyes; then
case "$target" in
case "$host" in
*-*-darwin*)
AC_MSG_RESULT(yes)
LIBS="$LIBS -framework OpenGL"
@ -448,7 +448,7 @@ int main(int argc,char * argv[]) {
dnl Some target detection and actions for them
case "$target" in
case "$host" in
*-*-cygwin* | *-*-mingw32*)
LIBS="$LIBS -lwinmm"
AC_CHECK_HEADERS(ddraw.h)
@ -486,7 +486,7 @@ case "$target" in
esac
dnl Some stuff for the icon.
case "$target" in
case "$host" in
*-*-cygwin* | *-*-mingw32*)
dnl Some stuff for the ico
AC_CHECK_TOOL(WINDRES, windres, :)

View File

@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*-
.TH DOSBOX 1 "May 27, 2009"
.TH DOSBOX 1 "Feb 26, 2010"
.\" Please adjust this date whenever revising the manpage.
.SH NAME
dosbox \- an x86/DOS emulator with sound/graphics
@ -9,6 +9,7 @@ dosbox \- an x86/DOS emulator with sound/graphics
.B [\-startmapper]
.B [\-noautoexec]
.B [\-securemode]
.B [\-userconf]
.BI "[\-scaler " scaler ]
.BI "[\-forcescaler " scaler ]
.BI "[\-conf " configfile ]
@ -27,6 +28,12 @@ dosbox \- an x86/DOS emulator with sound/graphics
.B dosbox \-printconf
.LP
.B dosbox \-eraseconf
.LP
.B dosbox \-resetconf
.LP
.B dosbox \-erasemapper
.LP
.B dosbox \-resetmapper
.SH DESCRIPTION
This manual page briefly documents
.BR "dosbox" ", an x86/DOS emulator."
@ -57,6 +64,10 @@ at the end of
(which in turn disables any changes to how the drives are mounted
.RB "inside " dosbox )
.TP
.B \-userconf
Load the configuration file located in ~/.dosbox. Can be combined with
.RB "the " \-conf " option."
.TP
.BI \-scaler " scaler"
.RI "Uses the graphical scaler specified by " scaler ". See the configuration"
file for the available scalers
@ -100,13 +111,16 @@ You can specify this command more than once. In this case it will
.RI " move to second " program " if the first one fails to start."
.TP
.BI \-opencaptures " program"
.RI "calls " program " with as first paramater the location of the captures folder."
.RI "calls " program " with as first parameter the location of the captures folder."
.TP
.B \-printconf
prints the location of the default configuration file.
.TP
.B \-eraseconf
.B \-eraseconf, \-resetconf
removes the default configuration file.
.TP
.B \-erasemapper, \-resetmapper
removes the mapperfile configured in the clean default configuration file.
.SH "INTERNAL COMMANDS"
.B dosbox
supports most of the DOS commands found in command.com. In addition, the

View File

@ -23,7 +23,7 @@
// 1: complex scalers off, scaler cache off, all simple scalers on
// 2: complex scalers off, scaler cache on
// 3: complex scalers on
#define RENDER_USE_ADVANCED_SCALERS 3
#define RENDER_USE_ADVANCED_SCALERS 2
#include "../src/gui/render_scalers.h"
@ -91,7 +91,7 @@ extern Render_t render;
extern ScalerLineHandler_t RENDER_DrawLine;
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool dblw,bool dblh);
bool RENDER_StartUpdate(void);
void RENDER_EndUpdate( );
void RENDER_EndUpdate(bool abort);
void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue);

View File

@ -45,6 +45,11 @@
#include <string>
#endif
#ifndef CH_CSTDIO
#define CH_CSTDIO
#include <cstdio>
#endif
class Hex {
private:

View File

@ -111,6 +111,12 @@ typedef struct {
Bit32u full_enable_and_set_reset;
} VGA_Config;
typedef enum {
PART,
LINE,
//EGALINE
} Drawmode;
typedef struct {
bool resizing;
Bitu width;
@ -144,6 +150,7 @@ typedef struct {
double hdend, htotal;
double parts;
} delay;
Bitu bpp;
double aspect_ratio;
bool double_scan;
bool doublewidth,doubleheight;
@ -156,6 +163,7 @@ typedef struct {
Bit8u count,delay;
Bit8u enabled;
} cursor;
Drawmode mode;
bool vret_triggered;
} VGA_Draw;
@ -216,7 +224,7 @@ typedef struct {
Bit8u htotal;
Bit8u hdend;
Bit8u hsyncp;
Bit8u syncw;
Bit8u hsyncw;
Bit8u vtotal;
Bit8u vdend;
Bit8u vadjust;
@ -262,7 +270,12 @@ typedef struct {
Bit8u color_plane_enable;
Bit8u color_select;
Bit8u index;
Bit8u enabled;
Bit8u disabled; // Used for disabling the screen.
// Bit0: screen disabled by attribute controller index
// Bit1: screen disabled by sequencer index 1 bit 5
// These are put together in one variable for performance reasons:
// the line drawing function is called maybe 60*480=28800 times/s,
// and we only need to check one variable for zero this way.
} VGA_Attr;
typedef struct {
@ -367,8 +380,6 @@ typedef struct {
typedef struct {
VGAModes mode; /* The mode the vga system is in */
VGAModes lastmode;
Bits screenflip;
Bit8u misc_output;
VGA_Draw draw;
VGA_Config config;
@ -397,6 +408,8 @@ typedef struct {
} VGA_Type;
/* Hercules Palette function */
void Herc_Palette(void);
/* Functions for different resolutions */
void VGA_SetMode(VGAModes mode);

1
scripts/captures.bat Normal file
View File

@ -0,0 +1 @@
DOSBox.exe -opencaptures explorer.exe

View File

@ -1,8 +1,8 @@
!define VER_MAYOR 0
!define VER_MINOR 73
!define VER_MINOR 74
!define APP_NAME "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer"
!define COMP_NAME "DOSBox Team"
!define COPYRIGHT "Copyright © 2002-2009 DOSBox Team"
!define COPYRIGHT "Copyright © 2002-2010 DOSBox Team"
!define DESCRIPTION "DOSBox Installer"
VIProductVersion "${VER_MAYOR}.${VER_MINOR}.0.0"
@ -47,44 +47,57 @@ SetShellVarContext all
; Put file there
CreateDirectory "$INSTDIR\zmbv"
CreateDirectory "$INSTDIR\Video Codec"
CreateDirectory "$INSTDIR\Documentation"
SetOutPath "$INSTDIR\Documentation"
File /oname=README.txt README
File /oname=COPYING.txt COPYING
File /oname=THANKS.txt THANKS
File /oname=NEWS.txt NEWS
File /oname=AUTHORS.txt AUTHORS
File /oname=INSTALL.txt INSTALL
File DOSBox.exe
SetOutPath "$INSTDIR"
File "/oname=DOSBox ${VER_MAYOR}.${VER_MINOR} Manual.txt" README
File "/oname=DOSBox.exe" DOSBox.exe
File SDL.dll
File SDL_net.dll
File /oname=zmbv\zmbv.dll zmbv.dll
File /oname=zmbv\zmbv.inf zmbv.inf
File /oname=zmbv\README.txt README.video
File "/oname=Video Codec\zmbv.dll" zmbv.dll
File "/oname=Video Codec\zmbv.inf" zmbv.inf
File "/oname=Video Codec\Video Instructions.txt" README.video
File "/oname=DOSBox ${VER_MAYOR}.${VER_MINOR} Options.bat" editconf.bat
File "/oname=Reset KeyMapper.bat" resetmapper.bat
File "/oname=Reset Options.bat" resetconf.bat
File "/oname=Screenshots & Recordings.bat" captures.bat
CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}"
CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video"
CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.lnk" "$INSTDIR\DOSBox.exe" "" "$INSTDIR\DOSBox.exe" 0
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox (noconsole).lnk" "$INSTDIR\DOSBox.exe" "-noconsole" "$INSTDIR\DOSBox.exe" 0
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\README.lnk" "$INSTDIR\README.txt"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration\Edit Configuration.lnk" "$INSTDIR\DOSBox.exe" "-editconf notepad.exe -editconf $\"%SystemRoot%\system32\notepad.exe$\" -editconf $\"%WINDIR%\notepad.exe$\""
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration\Reset Configuration.lnk" "$INSTDIR\DOSBox.exe" "-eraseconf"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Capture folder.lnk" "$INSTDIR\DOSBox.exe" "-opencaptures explorer.exe"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Video instructions.lnk" "$INSTDIR\zmbv\README.txt"
CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras"
CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Video"
CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Options"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk" "$INSTDIR\DOSBox.exe" "-userconf" "$INSTDIR\DOSBox.exe" 0
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox ${VER_MAYOR}.${VER_MINOR} Manual.lnk" "$INSTDIR\Documentation\README.txt"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\DOSBox ${VER_MAYOR}.${VER_MINOR} (noconsole).lnk" "$INSTDIR\DOSBox.exe" "-noconsole -userconf" "$INSTDIR\DOSBox.exe" 0
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Screenshots & Recordings.lnk" "$INSTDIR\DOSBox.exe" "-opencaptures explorer.exe"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Options\DOSBox ${VER_MAYOR}.${VER_MINOR} Options.lnk" "$INSTDIR\DOSBox.exe" "-editconf notepad.exe -editconf $\"%SystemRoot%\system32\notepad.exe$\" -editconf $\"%WINDIR%\notepad.exe$\""
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Options\Reset Options.lnk" "$INSTDIR\DOSBox.exe" "-eraseconf"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Options\Reset KeyMapper.lnk" "$INSTDIR\DOSBox.exe" "-erasemapper"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Video\Video instructions.lnk" "$INSTDIR\Video Codec\Video Instructions.txt"
;change outpath so the working directory gets set to zmbv
SetOutPath "$INSTDIR\zmbv"
SetOutPath "$INSTDIR\Video Codec"
; Shortcut creation depends on wether we are 9x of NT
ClearErrors
ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
IfErrors we_9x we_nt
we_nt:
;shortcut for win NT
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Install movie codec.lnk" "rundll32" "setupapi,InstallHinfSection DefaultInstall 128 $INSTDIR\zmbv\zmbv.inf"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Video\Install movie codec.lnk" "rundll32" "setupapi,InstallHinfSection DefaultInstall 128 $INSTDIR\Video Codec\zmbv.inf"
goto end
we_9x:
;shortcut for we_9x
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Install movie codec.lnk" "rundll" "setupx.dll,InstallHinfSection DefaultInstall 128 $INSTDIR\zmbv\zmbv.inf"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Video\Install movie codec.lnk" "rundll" "setupx.dll,InstallHinfSection DefaultInstall 128 $INSTDIR\Video Codec\zmbv.inf"
end:
SetOutPath $INSTDIR
WriteUninstaller "uninstall.exe"
@ -102,9 +115,9 @@ SectionEnd ; end the section
Section "Desktop Shortcut" SecDesktop
SetShellVarContext all
CreateShortCut "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk" "$INSTDIR\DOSBox.exe" "" "$INSTDIR\DOSBox.exe" 0
CreateShortCut "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk" "$INSTDIR\DOSBox.exe" "-userconf" "$INSTDIR\DOSBox.exe" 0
SectionEnd ; end the section
SectionEnd ; end the section
UninstallText "This will uninstall DOSBox v${VER_MAYOR}.${VER_MINOR}. Hit next to continue."
@ -117,40 +130,54 @@ SetShellVarContext all
Delete "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk"
; remove registry keys
; remove files
Delete $INSTDIR\README.txt
Delete $INSTDIR\COPYING.txt
Delete $INSTDIR\THANKS.txt
Delete $INSTDIR\NEWS.txt
Delete $INSTDIR\AUTHORS.txt
Delete $INSTDIR\INSTALL.txt
Delete $INSTDIR\DOSBox.exe
Delete $INSTDIR\Documentation\README.txt
Delete $INSTDIR\Documentation\COPYING.txt
Delete $INSTDIR\Documentation\THANKS.txt
Delete $INSTDIR\Documentation\NEWS.txt
Delete $INSTDIR\Documentation\AUTHORS.txt
Delete $INSTDIR\Documentation\INSTALL.txt
Delete "$INSTDIR\DOSBox ${VER_MAYOR}.${VER_MINOR} Manual.txt"
Delete "$INSTDIR\DOSBox.exe"
Delete $INSTDIR\SDL.dll
Delete $INSTDIR\SDL_net.dll
Delete $INSTDIR\zmbv\zmbv.dll
Delete $INSTDIR\zmbv\zmbv.inf
Delete $INSTDIR\zmbv\README.txt
Delete "$INSTDIR\Video Codec\zmbv.dll"
Delete "$INSTDIR\Video Codec\zmbv.inf"
Delete "$INSTDIR\Video Codec\Video Instructions.txt"
;Files left by sdl taking over the console
Delete $INSTDIR\stdout.txt
Delete $INSTDIR\stderr.txt
Delete "$INSTDIR\DOSBox ${VER_MAYOR}.${VER_MINOR} Options.bat"
Delete "$INSTDIR\Reset KeyMapper.bat"
Delete "$INSTDIR\Reset Options.bat"
Delete "$INSTDIR\Screenshots & Recordings.bat"
; MUST REMOVE UNINSTALLER, too
Delete $INSTDIR\uninstall.exe
; remove shortcuts, if any.
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Uninstall.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\README.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox (noconsole).lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration\Edit Configuration.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration\Reset Configuration.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Capture folder.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Install movie codec.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Video instructions.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox ${VER_MAYOR}.${VER_MINOR} Manual.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\DOSBox ${VER_MAYOR}.${VER_MINOR} (noconsole).lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Uninstall.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Screenshots & Recordings.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Options\DOSBox ${VER_MAYOR}.${VER_MINOR} Options.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Options\Reset Options.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Options\Reset KeyMapper.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Video\Video instructions.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Video\Install movie codec.lnk"
; remove shortcuts, if any.
; remove directories used.
RMDir "$INSTDIR\zmbv"
RMDir "$INSTDIR\Documentation"
RMDir "$INSTDIR\Video Codec"
RMDir "$INSTDIR"
RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration"
RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video"
RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Options"
RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras\Video"
RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Extras"
RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}"
SectionEnd

1
scripts/editconf.bat Normal file
View File

@ -0,0 +1 @@
DOSBox.exe -editconf notepad.exe -editconf %SystemRoot%\system32\notepad.exe -editconf %WINDIR%\notepad.exe

1
scripts/resetconf.bat Normal file
View File

@ -0,0 +1 @@
DOSBox.exe -resetconf

1
scripts/resetmapper.bat Normal file
View File

@ -0,0 +1 @@
DOSBox.exe -resetmapper

View File

@ -423,7 +423,13 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
}
phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction
phys_writeb(physAddress+0x02,(Bit8u)0xCB); //A RETF Instruction
return (use_cb?7:3);
phys_writeb(physAddress+0x03,(Bit8u)0x51); // push cx
phys_writeb(physAddress+0x04,(Bit8u)0xB9); // mov cx,
phys_writew(physAddress+0x05,(Bit16u)0x0140); // 0x140
phys_writew(physAddress+0x07,(Bit16u)0xFEE2); // loop $-2
phys_writeb(physAddress+0x09,(Bit8u)0x59); // pop cx
phys_writeb(physAddress+0x0A,(Bit8u)0xCF); //An IRET Instruction
return (use_cb?15:11);
default:
E_Exit("CALLBACK:Setup:Illegal type %d",type);

View File

@ -1546,7 +1546,7 @@ Bitu CPU_SIDT_limit(void) {
return cpu.idt.GetLimit();
}
static bool printed_cycles_auto_info = false;
void CPU_SET_CRX(Bitu cr,Bitu value) {
switch (cr) {
case 0:
@ -1567,6 +1567,10 @@ void CPU_SET_CRX(Bitu cr,Bitu value) {
CPU_Cycles=0;
CPU_OldCycleMax=CPU_CycleMax;
GFX_SetTitle(CPU_CyclePercUsed,-1,false);
if(!printed_cycles_auto_info) {
printed_cycles_auto_info = true;
LOG_MSG("DOSBox switched to max cycles, because of the setting: cycles=auto. If the game runs too fast try a fixed cycles amount in DOSBox's options.");
}
} else {
GFX_SetTitle(-1,-1,false);
}
@ -2099,8 +2103,8 @@ static void CPU_CycleIncrease(bool pressed) {
if (!pressed) return;
if (CPU_CycleAutoAdjust) {
CPU_CyclePercUsed+=5;
if (CPU_CyclePercUsed>100) CPU_CyclePercUsed=100;
LOG_MSG("CPU:%d percent",CPU_CyclePercUsed);
if (CPU_CyclePercUsed>105) CPU_CyclePercUsed=105;
LOG_MSG("CPU speed: max %d percent.",CPU_CyclePercUsed);
GFX_SetTitle(CPU_CyclePercUsed,-1,false);
} else {
Bit32s old_cycles=CPU_CycleMax;
@ -2112,7 +2116,10 @@ static void CPU_CycleIncrease(bool pressed) {
CPU_CycleLeft=0;CPU_Cycles=0;
if (CPU_CycleMax==old_cycles) CPU_CycleMax++;
LOG_MSG("CPU:%d cycles",CPU_CycleMax);
if(CPU_CycleMax > 15000 )
LOG_MSG("CPU speed: fixed %d cycles. If you need more than 20000, try core=dynamic in DOSBox's options.",CPU_CycleMax);
else
LOG_MSG("CPU speed: fixed %d cycles.",CPU_CycleMax);
GFX_SetTitle(CPU_CycleMax,-1,false);
}
}
@ -2122,7 +2129,10 @@ static void CPU_CycleDecrease(bool pressed) {
if (CPU_CycleAutoAdjust) {
CPU_CyclePercUsed-=5;
if (CPU_CyclePercUsed<=0) CPU_CyclePercUsed=1;
LOG_MSG("CPU:%d percent",CPU_CyclePercUsed);
if(CPU_CyclePercUsed <=70)
LOG_MSG("CPU speed: max %d percent. If the game runs too fast, try a fixed cycles amount in DOSBox's options.",CPU_CyclePercUsed);
else
LOG_MSG("CPU speed: max %d percent.",CPU_CyclePercUsed);
GFX_SetTitle(CPU_CyclePercUsed,-1,false);
} else {
if (CPU_CycleDown < 100) {
@ -2132,7 +2142,7 @@ static void CPU_CycleDecrease(bool pressed) {
}
CPU_CycleLeft=0;CPU_Cycles=0;
if (CPU_CycleMax <= 0) CPU_CycleMax=1;
LOG_MSG("CPU:%d cycles",CPU_CycleMax);
LOG_MSG("CPU speed: fixed %d cycles.",CPU_CycleMax);
GFX_SetTitle(CPU_CycleMax,-1,false);
}
}
@ -2246,7 +2256,7 @@ public:
int percval=0;
std::istringstream stream(str);
stream >> percval;
if ((percval>0) && (percval<=100)) CPU_CyclePercUsed=(Bit32s)percval;
if ((percval>0) && (percval<=105)) CPU_CyclePercUsed=(Bit32s)percval;
} else if (str=="limit") {
cmdnum++;
if (cmd.FindCommand(cmdnum,str)) {
@ -2271,7 +2281,7 @@ public:
int percval=0;
std::istringstream stream(str);
stream >> percval;
if ((percval>0) && (percval<=100)) CPU_CyclePercUsed=(Bit32s)percval;
if ((percval>0) && (percval<=105)) CPU_CyclePercUsed=(Bit32s)percval;
} else if (str=="limit") {
cmdnum++;
if (cmd.FindCommand(cmdnum,str)) {

View File

@ -76,6 +76,7 @@ static void DrawVariables(void);
char* AnalyzeInstruction(char* inst, bool saveSelector);
Bit32u GetHexValue(char* str, char*& hex);
#if 0
class DebugPageHandler : public PageHandler {
public:
Bitu readb(PhysPt /*addr*/) {
@ -90,10 +91,8 @@ public:
}
void writed(PhysPt /*addr*/,Bitu /*val*/) {
}
};
#endif
class DEBUG;
@ -123,7 +122,6 @@ static char curSelectorName[3] = { 0,0,0 };
static Segment oldsegs[6];
static Bitu oldflags,oldcpucpl;
DBGBlock dbg;
static Bitu input_count;
Bitu cycle_count;
static bool debugging;
@ -136,23 +134,34 @@ static void SetColor(Bitu test) {
}
}
#define MAXCMDLEN 254
struct SCodeViewData {
int cursorPos;
int cursorPos;
Bit16u firstInstSize;
Bit16u useCS;
Bit32u useEIPlast, useEIPmid;
Bit32u useEIP;
Bit16u useCS;
Bit32u useEIPlast, useEIPmid;
Bit32u useEIP;
Bit16u cursorSeg;
Bit32u cursorOfs;
bool inputMode;
char inputStr[255];
char prevInputStr[255];
Bit32u cursorOfs;
bool ovrMode;
char inputStr[MAXCMDLEN+1];
char suspInputStr[MAXCMDLEN+1];
int inputPos;
} codeViewData;
static Bit16u dataSeg;
static Bit32u dataOfs;
static bool showExtend = true;
static Bit16u dataSeg;
static Bit32u dataOfs;
static bool showExtend = true;
static void ClearInputLine(void) {
codeViewData.inputStr[0] = 0;
codeViewData.inputPos = 0;
}
// History stuff
#define MAX_HIST_BUFFER 50
static list<string> histBuff;
static list<string>::iterator histBuffPos = histBuff.end();
/***********/
/* Helpers */
@ -775,6 +784,8 @@ static void DrawCode(void) {
wattrset(dbg.win_code,COLOR_PAIR(PAIR_GREEN_BLACK));
if (codeViewData.cursorPos==-1) {
codeViewData.cursorPos = i; // Set Cursor
}
if (i == codeViewData.cursorPos) {
codeViewData.cursorSeg = SegValue(cs);
codeViewData.cursorOfs = disEIP;
}
@ -837,12 +848,18 @@ static void DrawCode(void) {
wattrset(dbg.win_code,0);
if (!debugging) {
mvwprintw(dbg.win_code,10,0,"(Running)",codeViewData.inputStr);
} else {
if(!*codeViewData.inputStr) { //Clear old commands
mvwprintw(dbg.win_code,10,0," ");
}
mvwprintw(dbg.win_code,10,0,"-> %s_ ",codeViewData.inputStr);
mvwprintw(dbg.win_code,10,0,"%s","(Running)");
wclrtoeol(dbg.win_code);
} else {
//TODO long lines
char* dispPtr = codeViewData.inputStr;
char* curPtr = &codeViewData.inputStr[codeViewData.inputPos];
mvwprintw(dbg.win_code,10,0,"%c-> %s%c",
(codeViewData.ovrMode?'O':'I'),dispPtr,(*curPtr?' ':'_'));
wclrtoeol(dbg.win_code); // not correct in pdcurses if full line
if (*curPtr) {
mvwchgat(dbg.win_code,10,(curPtr-dispPtr+4),1,0,(PAIR_BLACK_GREY),NULL);
}
}
wrefresh(dbg.win_code);
@ -1121,6 +1138,7 @@ bool ParseCommand(char* str) {
DEBUG_ShowMsg("DEBUG: Set code overview to %04X:%04X\n",codeSeg,codeOfs);
codeViewData.useCS = codeSeg;
codeViewData.useEIP = codeOfs;
codeViewData.cursorPos = 0;
return true;
};
@ -1226,6 +1244,7 @@ bool ParseCommand(char* str) {
DEBUG_ShowMsg("DEBUG: Set code overview to interrupt handler %X\n",intNr);
codeViewData.useCS = mem_readw(intNr*4+2);
codeViewData.useEIP = mem_readw(intNr*4);
codeViewData.cursorPos = 0;
return true;
}
};
@ -1259,7 +1278,8 @@ bool ParseCommand(char* str) {
if (command == "HELP" || command == "?") {
DEBUG_ShowMsg("Debugger commands (enter all values in hex or as register):\n");
DEBUG_ShowMsg("--------------------------------------------------------------------------\n");
DEBUG_ShowMsg("F3/F6 - Re-enter previous command.\n");
DEBUG_ShowMsg("F3/F6 - Previous command in history.\n");
DEBUG_ShowMsg("F4/F7 - Next command in history.\n");
DEBUG_ShowMsg("F5 - Run.\n");
DEBUG_ShowMsg("F9 - Set/Remove breakpoint.\n");
DEBUG_ShowMsg("F10/F11 - Step over / trace into instruction.\n");
@ -1476,12 +1496,12 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) {
if (jmp) {
pos = strchr(instu,'$');
if (pos) {
pos = strchr(instu,'+');
if (pos) {
strcpy(result,"(down)");
} else {
strcpy(result,"(up)");
}
pos = strchr(instu,'+');
if (pos) {
strcpy(result,"(down)");
} else {
strcpy(result,"(up)");
}
}
} else {
sprintf(result,"(no jmp)");
@ -1497,6 +1517,11 @@ Bit32u DEBUG_CheckKeys(void) {
if (key>0) {
#if defined(WIN32) && defined(__PDCURSES__)
switch (key) {
case PADENTER: key=0x0A; break;
case PADSLASH: key='/'; break;
case PADSTAR: key='*'; break;
case PADMINUS: key='-'; break;
case PADPLUS: key='+'; break;
case ALT_D:
if (ungetch('D') != ERR) key=27;
break;
@ -1518,7 +1543,7 @@ Bit32u DEBUG_CheckKeys(void) {
case 27: // escape (a bit slow): Clears line. and processes alt commands.
key=getch();
if(key < 0) { //Purely escape Clear line
codeViewData.inputStr[0] = 0;
ClearInputLine();
break;
}
@ -1584,23 +1609,54 @@ Bit32u DEBUG_CheckKeys(void) {
case KEY_END: // End: scroll log page down
DEBUG_RefreshPage(1);
break;
case KEY_F(6): // Re-enter previous command (f1-f4 generate rubbish at my place)
case KEY_F(3): // Re-enter previous command
// copy prevInputStr back into inputStr
safe_strncpy(codeViewData.inputStr, codeViewData.prevInputStr, sizeof(codeViewData.inputStr));
case KEY_IC: // Insert: toggle insert/overwrite
codeViewData.ovrMode = !codeViewData.ovrMode;
break;
case KEY_LEFT: // move to the left in command line
if (codeViewData.inputPos > 0) codeViewData.inputPos--;
break;
case KEY_RIGHT: // move to the right in command line
if (codeViewData.inputStr[codeViewData.inputPos]) codeViewData.inputPos++;
break;
case KEY_F(6): // previous command (f1-f4 generate rubbish at my place)
case KEY_F(3): // previous command
if (histBuffPos == histBuff.begin()) break;
if (histBuffPos == histBuff.end()) {
// copy inputStr to suspInputStr so we can restore it
safe_strncpy(codeViewData.suspInputStr, codeViewData.inputStr, sizeof(codeViewData.suspInputStr));
}
safe_strncpy(codeViewData.inputStr,(*--histBuffPos).c_str(),sizeof(codeViewData.inputStr));
codeViewData.inputPos = strlen(codeViewData.inputStr);
break;
case KEY_F(7): // next command (f1-f4 generate rubbish at my place)
case KEY_F(4): // next command
if (histBuffPos == histBuff.end()) break;
if (++histBuffPos != histBuff.end()) {
safe_strncpy(codeViewData.inputStr,(*histBuffPos).c_str(),sizeof(codeViewData.inputStr));
} else {
// copy suspInputStr back into inputStr
safe_strncpy(codeViewData.inputStr, codeViewData.suspInputStr, sizeof(codeViewData.inputStr));
}
codeViewData.inputPos = strlen(codeViewData.inputStr);
break;
case KEY_F(5): // Run Program
debugging=false;
CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true);
ignoreAddressOnce = SegPhys(cs)+reg_eip;
DOSBOX_SetNormalLoop();
break;
case KEY_F(9): // Set/Remove TBreakpoint
case KEY_F(9): // Set/Remove Breakpoint
{ PhysPt ptr = GetAddress(codeViewData.cursorSeg,codeViewData.cursorOfs);
if (CBreakpoint::IsBreakpoint(ptr)) CBreakpoint::DeleteBreakpoint(ptr);
else CBreakpoint::AddBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs, false);
if (CBreakpoint::IsBreakpoint(ptr)) {
CBreakpoint::DeleteBreakpoint(ptr);
DEBUG_ShowMsg("DEBUG: Breakpoint deletion success.\n");
}
else {
CBreakpoint::AddBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs, false);
DEBUG_ShowMsg("DEBUG: Set breakpoint at %04X:%04X\n",codeViewData.cursorSeg,codeViewData.cursorOfs);
}
}
break;
break;
case KEY_F(10): // Step over inst
if (StepOver()) return 0;
else {
@ -1621,28 +1677,54 @@ Bit32u DEBUG_CheckKeys(void) {
CBreakpoint::ignoreOnce = 0;
break;
case 0x0A: //Parse typed Command
codeViewData.inputMode = true;
codeViewData.inputStr[MAXCMDLEN] = '\0';
if(ParseCommand(codeViewData.inputStr)) {
// copy inputStr to prevInputStr so we can restore it if the user hits F3
safe_strncpy(codeViewData.prevInputStr, codeViewData.inputStr, sizeof(codeViewData.prevInputStr));
// clear input line ready for next command
codeViewData.inputStr[0] = 0;
char* cmd = ltrim(codeViewData.inputStr);
if (histBuff.empty() || *--histBuff.end()!=cmd)
histBuff.push_back(cmd);
if (histBuff.size() > MAX_HIST_BUFFER) histBuff.pop_front();
histBuffPos = histBuff.end();
ClearInputLine();
} else {
codeViewData.inputPos = strlen(codeViewData.inputStr);
}
break;
case KEY_BACKSPACE: //backspace (linux)
case 0x7f: // backspace in some terminal emulators (linux)
case 0x08: // delete
if (codeViewData.inputPos == 0) break;
codeViewData.inputPos--;
// fallthrough
case KEY_DC: // delete character
if ((codeViewData.inputPos<0) || (codeViewData.inputPos>=MAXCMDLEN)) break;
if (codeViewData.inputStr[codeViewData.inputPos] != 0) {
codeViewData.inputStr[MAXCMDLEN] = '\0';
for(char* p=&codeViewData.inputStr[codeViewData.inputPos];(*p=*(p+1));p++) {}
}
break;
default:
if ((key>=32) && (key<127)) {
if ((codeViewData.inputPos<0) || (codeViewData.inputPos>=MAXCMDLEN)) break;
codeViewData.inputStr[MAXCMDLEN] = '\0';
if (codeViewData.inputStr[codeViewData.inputPos] == 0) {
codeViewData.inputStr[codeViewData.inputPos++] = char(key);
codeViewData.inputStr[codeViewData.inputPos] = '\0';
} else if (!codeViewData.ovrMode) {
int len = (int) strlen(codeViewData.inputStr);
if (len < MAXCMDLEN) {
for(len++;len>codeViewData.inputPos;len--)
codeViewData.inputStr[len]=codeViewData.inputStr[len-1];
codeViewData.inputStr[codeViewData.inputPos++] = char(key);
}
} else {
codeViewData.inputStr[codeViewData.inputPos++] = char(key);
}
} else if (key==killchar()) {
ClearInputLine();
}
break;
case 0x107: //backspace (linux)
case 0x7f: //backspace in some terminal emulators (linux)
case 0x08: // delete
if (strlen(codeViewData.inputStr)>0) codeViewData.inputStr[strlen(codeViewData.inputStr)-1] = 0;
break;
default : if ((key>=32) && (key<=128) && (strlen(codeViewData.inputStr)<253)) {
Bit32u len = strlen(codeViewData.inputStr);
codeViewData.inputStr[len] = char(key);
codeViewData.inputStr[len+1] = 0;
}
break;
}
if (ret<0) return ret;
if (ret<0) return ret;
if (ret>0) {
ret=(*CallBack_Handlers[ret])();
if (ret) {
@ -1902,7 +1984,7 @@ static void LogInstruction(Bit16u segValue, Bit32u eipValue, ofstream& out) {
char ibytes[200]=""; char tmpc[200];
for (Bitu i=0; i<size; i++) {
Bit8u value;
if (mem_readb_checked(start+i,&value)) sprintf(tmpc,"?? ",value);
if (mem_readb_checked(start+i,&value)) sprintf(tmpc,"%s","?? ");
else sprintf(tmpc,"%02X ",value);
strcat(ibytes,tmpc);
}
@ -1958,7 +2040,6 @@ public:
safe_strncpy(filename,temp_line.c_str(),128);
// Read commandline
Bit16u i =2;
bool ok = false;
args[0] = 0;
for (;cmd->FindCommand(i++,temp_line)==true;) {
strncat(args,temp_line.c_str(),256);
@ -2027,8 +2108,7 @@ void DEBUG_SetupConsole(void) {
#endif
memset((void *)&dbg,0,sizeof(dbg));
debugging=false;
dbg.active_win=3;
input_count=0;
// dbg.active_win=3;
/* Start the Debug Gui */
DBGUI_StartUp();
}
@ -2037,6 +2117,7 @@ static void DEBUG_ShutDown(Section * /*sec*/) {
CBreakpoint::DeleteAll();
CDebugVar::DeleteAll();
curs_set(old_cursor_state);
endwin();
#ifndef WIN32
tcsetattr(0, TCSANOW,&consolesettings);
// printf("\e[0m\e[2J"); //Seems to destroy scrolling
@ -2049,11 +2130,11 @@ Bitu debugCallback;
void DEBUG_Init(Section* sec) {
MSG_Add("DEBUG_CONFIGFILE_HELP","Debugger related options.\n");
// MSG_Add("DEBUG_CONFIGFILE_HELP","Debugger related options.\n");
DEBUG_DrawScreen();
/* Add some keyhandlers */
MAPPER_AddHandler(DEBUG_Enable,MK_pause,MMOD2,"debugger","Debugger");
/* Clear the TBreakpoint list */
/* Reset code overview and input line */
memset((void*)&codeViewData,0,sizeof(codeViewData));
/* setup debug.com */
PROGRAMS_MakeFile("DEBUG.COM",DEBUG_ProgramStart);
@ -2154,7 +2235,7 @@ static void SaveMemory(Bitu seg, Bitu ofs1, Bit32u num) {
sprintf(buffer,"%04X:%04X ",seg,ofs1);
for (Bit16u x=0; x<16; x++) {
Bit8u value;
if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"?? ",value);
if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"%s","?? ");
else sprintf(temp,"%02X ",value);
strcat(buffer,temp);
}
@ -2167,7 +2248,7 @@ static void SaveMemory(Bitu seg, Bitu ofs1, Bit32u num) {
sprintf(buffer,"%04X:%04X ",seg,ofs1);
for (Bit16u x=0; x<num; x++) {
Bit8u value;
if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"?? ",value);
if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"%s","?? ");
else sprintf(temp,"%02X ",value);
strcat(buffer,temp);
}
@ -2229,7 +2310,7 @@ static void DrawVariables(void) {
Bit16u value;
if (mem_readw_checked(dv->GetAdr(),&value))
snprintf(buffer,DEBUG_VAR_BUF_LEN, "??????", value);
snprintf(buffer,DEBUG_VAR_BUF_LEN, "%s", "??????");
else
snprintf(buffer,DEBUG_VAR_BUF_LEN, "0x%04x", value);
@ -2248,8 +2329,6 @@ static void DrawVariables(void) {
const Bit32u LOGCPUMAX = 20000;
static Bit16u logCpuCS [LOGCPUMAX];
static Bit32u logCpuEIP[LOGCPUMAX];
static Bit32u logCount = 0;
struct TLogInst {
@ -2287,7 +2366,7 @@ void DEBUG_HeavyLogInstruction(void) {
PhysPt start = GetAddress(SegValue(cs),reg_eip);
char dline[200];
Bitu size = DasmI386(dline, start, reg_eip, cpu.code.big);
DasmI386(dline, start, reg_eip, cpu.code.big);
char* res = empty;
if (showExtend) {
res = AnalyzeInstruction(dline,false);

View File

@ -154,7 +154,7 @@ static void DrawBars(void) {
/* Show the Variable Overview bar */
mvaddstr(dbg.win_var->_begy-1,0, "---(Variable Overview )---");
/* Show the Output OverView */
mvaddstr(dbg.win_out->_begy-1,0, "---(OutPut/Input Scroll: home/end )---");
mvaddstr(dbg.win_out->_begy-1,0, "---(Output Scroll: home/end )---");
attrset(0);
}
@ -178,8 +178,8 @@ static void MakeSubWindows(void) {
dbg.win_var=subwin(dbg.win_main,4,win_main_maxx,outy,0);
outy+=5;
/* The Output Window */
dbg.win_out=subwin(dbg.win_main,win_main_maxy-outy-1,win_main_maxx,outy,0);
dbg.input_y=win_main_maxy-1;
dbg.win_out=subwin(dbg.win_main,win_main_maxy-outy,win_main_maxx,outy,0);
// dbg.input_y=win_main_maxy-1;
scrollok(dbg.win_out,TRUE);
DrawBars();
Draw_RegisterLayout();
@ -257,7 +257,7 @@ void LOG_StartUp(void) {
Prop_bool* Pbool = sect->Add_bool(buf,Property::Changeable::Always,true);
Pbool->Set_help("Enable/Disable logging of this type.");
}
MSG_Add("LOG_CONFIGFILE_HELP","Logging related options for the debugger.\n");
// MSG_Add("LOG_CONFIGFILE_HELP","Logging related options for the debugger.\n");
}

View File

@ -44,7 +44,10 @@ void DOS_SetError(Bit16u code) {
#define DATA_TRANSFERS_TAKE_CYCLES 1
#ifdef DATA_TRANSFERS_TAKE_CYCLES
#ifndef DOSBOX_CPU_H
#include "cpu.h"
#endif
static inline void modify_cycles(Bits value) {
if((4*value+5) < CPU_Cycles) {
CPU_Cycles -= 4*value;
@ -59,6 +62,20 @@ static inline void modify_cycles(Bits /* value */) {
return;
}
#endif
#define DOS_OVERHEAD 1
#ifdef DOS_OVERHEAD
#ifndef DOSBOX_CPU_H
#include "cpu.h"
#endif
static inline void overhead() {
reg_ip += 2;
}
#else
static inline void overhead() {
return;
}
#endif
#define DOSNAMEBUF 256
static Bitu DOS_21Handler(void) {
@ -121,6 +138,9 @@ static Bitu DOS_21Handler(void) {
switch (reg_dl) {
case 0xFF: /* Input */
{
//Simulate DOS overhead for timing sensitive games
//MM1
overhead();
//TODO Make this better according to standards
if (!DOS_GetSTDINStatus()) {
reg_al=0;
@ -201,6 +221,9 @@ static Bitu DOS_21Handler(void) {
case 0x0b: /* Get STDIN Status */
if (!DOS_GetSTDINStatus()) {reg_al=0x00;}
else {reg_al=0xFF;}
//Simulate some overhead for timing issues
//Tankwar menu (needs maybe even more)
overhead();
break;
case 0x0c: /* Flush Buffer and read STDIN call */
{
@ -369,6 +392,9 @@ static Bitu DOS_21Handler(void) {
reg_dh=(Bit8u)(seconds % 60);
reg_dl=(Bit8u)(ticks % 100);
}
//Simulate DOS overhead for timing-sensitive games
//Robomaze 2
overhead();
break;
case 0x2d: /* Set System Time */
LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Set System Time not supported");
@ -1061,7 +1087,7 @@ static Bitu DOS_20Handler(void) {
static Bitu DOS_27Handler(void) {
// Terminate & stay resident
Bit16u para = (reg_dx/16)+((reg_dx % 16)>0);
Bit16u psp = mem_readw(SegPhys(ss)+reg_sp+2);
Bit16u psp = dos.psp(); //mem_readw(SegPhys(ss)+reg_sp+2);
if (DOS_ResizeMemory(psp,&para)) DOS_Terminate(psp,true,0);
return CBRET_NONE;
}

View File

@ -213,8 +213,12 @@ bool DOS_NewPSP(Bit16u segment, Bit16u size) {
bool DOS_ChildPSP(Bit16u segment, Bit16u size) {
DOS_PSP psp(segment);
psp.MakeNew(size);
DOS_PSP psp_parent(psp.GetParent());
Bit16u parent_psp_seg = psp.GetParent();
DOS_PSP psp_parent(parent_psp_seg);
psp.CopyFileTable(&psp_parent,true);
psp.SetCommandTail(RealMake(parent_psp_seg,0x80));
psp.SetFCB1(RealMake(parent_psp_seg,0x5c));
psp.SetFCB2(RealMake(parent_psp_seg,0x6c));
psp.SetEnvironment(psp_parent.GetEnvironment());
psp.SetSize(size);
return true;
@ -412,7 +416,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) {
} else {
csip=RealMake(loadseg+head.initCS,head.initIP);
sssp=RealMake(loadseg+head.initSS,head.initSP);
if (head.initSP<4) E_Exit("stack underflow/wrap at EXEC");
if (head.initSP<4) LOG(LOG_EXEC,LOG_ERROR)("stack underflow/wrap at EXEC");
}
if (flags==LOAD) {
@ -434,7 +438,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) {
}
if (flags==LOADNGO) {
if ((reg_sp>0xfffe) || (reg_sp<18)) E_Exit("stack underflow/wrap at EXEC");
if ((reg_sp>0xfffe) || (reg_sp<18)) LOG(LOG_EXEC,LOG_ERROR)("stack underflow/wrap at EXEC");
/* Get Caller's program CS:IP of the stack and set termination address to that */
RealSetVec(0x22,RealMake(mem_readw(SegPhys(ss)+reg_sp+2),mem_readw(SegPhys(ss)+reg_sp)));
SaveRegisters();

View File

@ -50,7 +50,7 @@ Bitu DEBUG_EnableDebugger(void);
void MSCDEX_SetCDInterface(int intNr, int forceCD);
#ifdef HW_RVL
// Mounts a folder as a harddrive before starting the shell
// Designed for the Wii
int MountDOSBoxDir(char DriveLetter, const char *path) {
@ -118,7 +118,7 @@ int MountDOSBoxDir(char DriveLetter, const char *path) {
newdrive->dirCache.SetLabel(label.c_str(),false,true);
return 1;
}
#endif
class MOUNT : public Program {
public:
@ -1142,7 +1142,7 @@ public:
return;
}
} else {
WriteOut_NoParsing(MSG_Get("PROGRAM_IMGMOUNT_FORMAT_UNSUPPORTED"));
WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FORMAT_UNSUPPORTED"),fstype.c_str());
return;
}
@ -1292,7 +1292,7 @@ public:
case 0 : break;
case 1 : WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); break;
case 2 : WriteOut(MSG_Get("MSCDEX_ERROR_NOT_SUPPORTED")); break;
case 3 : WriteOut(MSG_Get("MSCDEX_ERROR_PATH")); break;
case 3 : WriteOut(MSG_Get("MSCDEX_ERROR_OPEN")); break;
case 4 : WriteOut(MSG_Get("MSCDEX_TOO_MANY_DRIVES")); break;
case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break;
case 6 : WriteOut(MSG_Get("MSCDEX_INVALID_FILEFORMAT")); break;
@ -1452,7 +1452,7 @@ void DOS_SetupPrograms(void) {
MSG_Add("MSCDEX_SUCCESS","MSCDEX installed.\n");
MSG_Add("MSCDEX_ERROR_MULTIPLE_CDROMS","MSCDEX: Failure: Drive-letters of multiple CDRom-drives have to be continuous.\n");
MSG_Add("MSCDEX_ERROR_NOT_SUPPORTED","MSCDEX: Failure: Not yet supported.\n");
MSG_Add("MSCDEX_ERROR_PATH","MSCDEX: Failure: Path not valid.\n");
MSG_Add("MSCDEX_ERROR_OPEN","MSCDEX: Failure: Invalid file or unable to open.\n");
MSG_Add("MSCDEX_TOO_MANY_DRIVES","MSCDEX: Failure: Too many CDRom-drives (max: 5). MSCDEX Installation failed.\n");
MSG_Add("MSCDEX_LIMITED_SUPPORT","MSCDEX: Mounted subdirectory: limited support.\n");
MSG_Add("MSCDEX_INVALID_FILEFORMAT","MSCDEX: Failure: File is either no iso/cue image or contains errors.\n");
@ -1553,7 +1553,7 @@ void DOS_SetupPrograms(void) {
"\033[33;1mCTRL-F10\033[0m : Capture/Release the mouse.\n"
"\033[33;1mCTRL-F11\033[0m : Slow down emulation (Decrease DOSBox Cycles).\n"
"\033[33;1mCTRL-F12\033[0m : Speed up emulation (Increase DOSBox Cycles).\n"
"\033[33;1mALT-F12\033[0m : Unlock speed (turbo button).\n"
"\033[33;1mALT-F12\033[0m : Unlock speed (turbo button/fast forward).\n"
);
MSG_Add("PROGRAM_BOOT_NOT_EXIST","Bootdisk file does not exist. Failing.\n");
MSG_Add("PROGRAM_BOOT_NOT_OPEN","Cannot open bootdisk file. Failing.\n");

View File

@ -248,6 +248,7 @@ void DOSBOX_RunMachine(void){
static void DOSBOX_UnlockSpeed( bool pressed ) {
static bool autoadjust = false;
if (pressed) {
LOG_MSG("Fast Forward ON");
ticksLocked = true;
if (CPU_CycleAutoAdjust) {
autoadjust = true;
@ -255,7 +256,8 @@ static void DOSBOX_UnlockSpeed( bool pressed ) {
CPU_CycleMax /= 3;
if (CPU_CycleMax<1000) CPU_CycleMax=1000;
}
} else {
} else {
LOG_MSG("Fast Forward OFF");
ticksLocked = false;
if (autoadjust) {
autoadjust = false;
@ -317,8 +319,13 @@ void DOSBOX_Init(void) {
SDLNetInited = false;
// Some frequently used option sets
#ifdef HW_RVL
const char *rates[] = { "22050", "44100", "48000", "32000", "16000", "11025", "8000", "49716", 0 };
const char *oplrates[] = { "22050", "49716", "44100", "48000", "32000", "16000", "11025", "8000", 0 };
#else
const char *rates[] = { "44100", "48000", "32000","22050", "16000", "11025", "8000", "49716", 0 };
const char *oplrates[] = { "44100", "49716", "48000", "32000","22050", "16000", "11025", "8000", 0 };
#endif
const char *ios[] = { "220", "240", "260", "280", "2a0", "2c0", "2e0", "300", 0 };
const char *irqssb[] = { "7", "5", "3", "9", "10", "11", "12", 0 };
const char *dmassb[] = { "1", "5", "0", "3", "6", "7", 0 };
@ -374,7 +381,8 @@ void DOSBOX_Init(void) {
Pmulti = secprop->Add_multi("scaler",Property::Changeable::Always," ");
Pmulti->SetValue("normal2x");
Pmulti->Set_help("Scaler used to enlarge/enhance low resolution modes. If 'forced' is appended,the scaler will be used even if the result might not be desired.");
Pmulti->Set_help("Scaler used to enlarge/enhance low resolution modes.\n"
" If 'forced' is appended, then the scaler will be used even if the result might not be desired.");
Pstring = Pmulti->GetSection()->Add_string("type",Property::Changeable::Always,"normal2x");
const char *scalers[] = {
@ -410,11 +418,13 @@ void DOSBOX_Init(void) {
Pmulti_remain = secprop->Add_multiremain("cycles",Property::Changeable::Always," ");
Pmulti_remain->Set_help(
"Amount of instructions DOSBox tries to emulate each millisecond. Setting this value too high results in sound dropouts and lags. Cycles can be set in 3 ways:\n"
"Amount of instructions DOSBox tries to emulate each millisecond.\n"
"Setting this value too high results in sound dropouts and lags.\n"
"Cycles can be set in 3 ways:\n"
" 'auto' tries to guess what a game needs.\n"
" It usually works, but can fail for certain games.\n"
" 'fixed #number' will set a fixed amount of cycles. This is what you usually need if 'auto' fails.\n"
" (Example: fixed 4000)\n"
" (Example: fixed 4000).\n"
" 'max' will allocate as much cycles as your computer is able to handle.\n");
const char* cyclest[] = { "auto","fixed","max","%u",0 };
@ -424,9 +434,9 @@ void DOSBOX_Init(void) {
Pstring = Pmulti_remain->GetSection()->Add_string("parameters",Property::Changeable::Always,"");
Pint = secprop->Add_int("cycleup",Property::Changeable::Always,500);
Pint = secprop->Add_int("cycleup",Property::Changeable::Always,10);
Pint->SetMinMax(1,1000000);
Pint->Set_help("Amount of cycles to increase/decrease with keycombo.");
Pint->Set_help("Amount of cycles to decrease/increase with keycombo.(CTRL-F11/CTRL-F12)");
Pint = secprop->Add_int("cycledown",Property::Changeable::Always,20);
Pint->SetMinMax(1,1000000);
@ -442,25 +452,30 @@ void DOSBOX_Init(void) {
secprop=control->AddSection_prop("mixer",&MIXER_Init);
Pbool = secprop->Add_bool("nosound",Property::Changeable::OnlyAtStart,false);
Pbool->Set_help("Enable silent mode, sound is still emulated though.");
#ifdef HW_RVL
Pint = secprop->Add_int("rate",Property::Changeable::OnlyAtStart,22050);
#else
Pint = secprop->Add_int("rate",Property::Changeable::OnlyAtStart,44100);
#endif
Pint->Set_values(rates);
Pint->Set_help("Mixer sample rate, setting any device's rate higher than this will probably lower their sound quality.");
#ifdef HW_RVL
const char *blocksizes[] = {
"2048", "4096", "8192", "1024", "512", "256", 0};
#ifdef HW_RVL
Pint = secprop->Add_int("blocksize",Property::Changeable::OnlyAtStart,512);
#else
const char *blocksizes[] = {
"1024", "2048", "4096", "8192", "512", "256", 0};
Pint = secprop->Add_int("blocksize",Property::Changeable::OnlyAtStart,2048);
#endif
Pint->Set_values(blocksizes);
Pint->Set_help("Mixer block size, larger blocks might help sound stuttering but sound will also be more lagged.");
Pint = secprop->Add_int("prebuffer",Property::Changeable::OnlyAtStart,10);
Pint = secprop->Add_int("prebuffer",Property::Changeable::OnlyAtStart,20);
Pint->SetMinMax(0,100);
Pint->Set_help("How many milliseconds of data to keep on top of the blocksize.");
secprop=control->AddSection_prop("midi",&MIDI_Init,true);//done
secprop->AddInitFunction(&MPU401_Init,true);//done
@ -476,7 +491,8 @@ void DOSBOX_Init(void) {
Pstring->Set_help("Device that will receive the MIDI data from MPU-401.");
Pstring = secprop->Add_string("midiconfig",Property::Changeable::WhenIdle,"");
Pstring->Set_help("Special configuration options for the device driver. This is usually the id of the device you want to use. See README for details.");
Pstring->Set_help("Special configuration options for the device driver. This is usually the id of the device you want to use.\n"
" See the README/Manual for more details.");
#if C_DEBUG
secprop=control->AddSection_prop("debug",&DEBUG_Init);
@ -517,8 +533,11 @@ void DOSBOX_Init(void) {
Pstring = secprop->Add_string("oplemu",Property::Changeable::WhenIdle,"default");
Pstring->Set_values(oplemus);
Pstring->Set_help("Provider for the OPL emulation. compat might provide better quality (see oplrate as well).");
#ifdef HW_RVL
Pint = secprop->Add_int("oplrate",Property::Changeable::WhenIdle,22050);
#else
Pint = secprop->Add_int("oplrate",Property::Changeable::WhenIdle,44100);
#endif
Pint->Set_values(oplrates);
Pint->Set_help("Sample rate of OPL music emulation. Use 49716 for highest quality (set the mixer rate accordingly).");
@ -526,8 +545,11 @@ void DOSBOX_Init(void) {
secprop=control->AddSection_prop("gus",&GUS_Init,true); //done
Pbool = secprop->Add_bool("gus",Property::Changeable::WhenIdle,false);
Pbool->Set_help("Enable the Gravis Ultrasound emulation.");
#ifdef HW_RVL
Pint = secprop->Add_int("gusrate",Property::Changeable::WhenIdle,22050);
#else
Pint = secprop->Add_int("gusrate",Property::Changeable::WhenIdle,44100);
#endif
Pint->Set_values(rates);
Pint->Set_help("Sample rate of Ultrasound emulation.");
@ -553,8 +575,11 @@ void DOSBOX_Init(void) {
secprop = control->AddSection_prop("speaker",&PCSPEAKER_Init,true);//done
Pbool = secprop->Add_bool("pcspeaker",Property::Changeable::WhenIdle,true);
Pbool->Set_help("Enable PC-Speaker emulation.");
#ifdef HW_RVL
Pint = secprop->Add_int("pcrate",Property::Changeable::WhenIdle,22050);
#else
Pint = secprop->Add_int("pcrate",Property::Changeable::WhenIdle,44100);
#endif
Pint->Set_values(rates);
Pint->Set_help("Sample rate of the PC-Speaker sound generation.");
@ -563,8 +588,12 @@ void DOSBOX_Init(void) {
Pstring = secprop->Add_string("tandy",Property::Changeable::WhenIdle,"auto");
Pstring->Set_values(tandys);
Pstring->Set_help("Enable Tandy Sound System emulation. For 'auto', emulation is present only if machine is set to 'tandy'.");
#ifdef HW_RVL
Pint = secprop->Add_int("tandyrate",Property::Changeable::WhenIdle,22050);
#else
Pint = secprop->Add_int("tandyrate",Property::Changeable::WhenIdle,44100);
#endif
Pint->Set_values(rates);
Pint->Set_help("Sample rate of the Tandy 3-Voice generation.");
@ -587,10 +616,11 @@ void DOSBOX_Init(void) {
"4axis_2 (supports one joystick, second joystick used),\n"
"fcs (Thrustmaster), ch (CH Flightstick).\n"
"none disables joystick emulation.\n"
"auto chooses emulation depending on real joystick(s).");
"auto chooses emulation depending on real joystick(s).\n"
"(Remember to reset dosbox's mapperfile if you saved it earlier)");
Pbool = secprop->Add_bool("timed",Property::Changeable::WhenIdle,true);
Pbool->Set_help("enable timed intervals for axis. (false is old style behaviour).");
Pbool->Set_help("enable timed intervals for axis. Experiment with this option, if your joystick drifts (away).");
Pbool = secprop->Add_bool("autofire",Property::Changeable::WhenIdle,false);
Pbool->Set_help("continuously fires as long as you keep the button pressed.");
@ -676,10 +706,11 @@ void DOSBOX_Init(void) {
secline=control->AddSection_line("autoexec",&AUTOEXEC_Init);
MSG_Add("AUTOEXEC_CONFIGFILE_HELP",
"Lines in this section will be run at startup.\n"
"You can put your MOUNT lines here.\n"
);
MSG_Add("CONFIGFILE_INTRO",
"# This is the configurationfile for DOSBox %s.\n"
"# Lines starting with a # are commentlines.\n"
"# This is the configurationfile for DOSBox %s. (Please use the latest version of DOSBox)\n"
"# Lines starting with a # are commentlines and are ignored by DOSBox.\n"
"# They are used to (briefly) document the effect of each option.\n");
MSG_Add("CONFIG_SUGGESTED_VALUES", "Possible values");

View File

@ -97,7 +97,7 @@ static Real64 FPU_FLD80(PhysPt addr) {
test.eind.l.lower = mem_readd(addr);
test.eind.l.upper = mem_readd(addr+4);
test.begin = mem_readw(addr+8);
Bit64s exp64 = (((test.begin&0x7fff) - BIAS80));
Bit64s blah = ((exp64 >0)?exp64:-exp64)&0x3ff;
Bit64s exp64final = ((exp64 >0)?blah:-blah) +BIAS64;
@ -106,6 +106,11 @@ static Real64 FPU_FLD80(PhysPt addr) {
Bit64s sign = (test.begin&0x8000)?1:0;
FPU_Reg result;
result.ll = (sign <<63)|(exp64final << 52)| mant64;
if(test.eind.l.lower == 0 && test.eind.l.upper == 0x80000000 && (test.begin&0x7fff) == 0x7fff) {
//Detect INF and -INF (score 3.11 when drawing a slur.)
result.d = sign?-HUGE_VAL:HUGE_VAL;
}
return result.d;
//mant64= test.mant80/2***64 * 2 **53

View File

@ -201,7 +201,7 @@ static void RENDER_Halt( void ) {
}
extern Bitu PIC_Ticks;
void RENDER_EndUpdate( void ) {
void RENDER_EndUpdate( bool abort ) {
if (GCC_UNLIKELY(!render.updating))
return;
RENDER_DrawLine = RENDER_EmptyLineHandler;
@ -220,7 +220,7 @@ void RENDER_EndUpdate( void ) {
flags, fps, (Bit8u *)&scalerSourceCache, (Bit8u*)&render.pal.rgb );
}
if ( render.scale.outWrite ) {
GFX_EndUpdate( Scaler_ChangedLines );
GFX_EndUpdate( abort? NULL : Scaler_ChangedLines );
render.frameskip.hadSkip[render.frameskip.index] = 0;
} else {
#if 0

View File

@ -1776,7 +1776,7 @@ static void CreateLayout(void) {
#define BH 20
#define DX 5
#define PX(_X_) ((_X_)*BW + DX)
#define PY(_Y_) (30+(_Y_)*BH)
#define PY(_Y_) (10+(_Y_)*BH)
AddKeyButtonEvent(PX(0),PY(0),BW,BH,"ESC","esc",KBD_esc);
for (i=0;i<12;i++) AddKeyButtonEvent(PX(2+i),PY(0),BW,BH,combo_f[i].title,combo_f[i].entry,combo_f[i].key);
for (i=0;i<14;i++) AddKeyButtonEvent(PX( i),PY(1),BW,BH,combo_1[i].title,combo_1[i].entry,combo_1[i].key);
@ -1801,62 +1801,71 @@ static void CreateLayout(void) {
AddKeyButtonEvent(PX(14),PY(5),BW*2,BH,"CTRL","rctrl",KBD_rightctrl);
/* Arrow Keys */
AddKeyButtonEvent(PX(0),PY(7),BW,BH,"PRT","printscreen",KBD_printscreen);
AddKeyButtonEvent(PX(1),PY(7),BW,BH,"SCL","scrolllock",KBD_scrolllock);
AddKeyButtonEvent(PX(2),PY(7),BW,BH,"PAU","pause",KBD_pause);
AddKeyButtonEvent(PX(0),PY(8),BW,BH,"INS","insert",KBD_insert);
AddKeyButtonEvent(PX(1),PY(8),BW,BH,"HOM","home",KBD_home);
AddKeyButtonEvent(PX(2),PY(8),BW,BH,"PUP","pageup",KBD_pageup);
AddKeyButtonEvent(PX(0),PY(9),BW,BH,"DEL","delete",KBD_delete);
AddKeyButtonEvent(PX(1),PY(9),BW,BH,"END","end",KBD_end);
AddKeyButtonEvent(PX(2),PY(9),BW,BH,"PDN","pagedown",KBD_pagedown);
AddKeyButtonEvent(PX(1),PY(10),BW,BH,"\x18","up",KBD_up);
AddKeyButtonEvent(PX(0),PY(11),BW,BH,"\x1B","left",KBD_left);
AddKeyButtonEvent(PX(1),PY(11),BW,BH,"\x19","down",KBD_down);
AddKeyButtonEvent(PX(2),PY(11),BW,BH,"\x1A","right",KBD_right);
#define XO 17
#define YO 0
AddKeyButtonEvent(PX(XO+0),PY(YO),BW,BH,"PRT","printscreen",KBD_printscreen);
AddKeyButtonEvent(PX(XO+1),PY(YO),BW,BH,"SCL","scrolllock",KBD_scrolllock);
AddKeyButtonEvent(PX(XO+2),PY(YO),BW,BH,"PAU","pause",KBD_pause);
AddKeyButtonEvent(PX(XO+0),PY(YO+1),BW,BH,"INS","insert",KBD_insert);
AddKeyButtonEvent(PX(XO+1),PY(YO+1),BW,BH,"HOM","home",KBD_home);
AddKeyButtonEvent(PX(XO+2),PY(YO+1),BW,BH,"PUP","pageup",KBD_pageup);
AddKeyButtonEvent(PX(XO+0),PY(YO+2),BW,BH,"DEL","delete",KBD_delete);
AddKeyButtonEvent(PX(XO+1),PY(YO+2),BW,BH,"END","end",KBD_end);
AddKeyButtonEvent(PX(XO+2),PY(YO+2),BW,BH,"PDN","pagedown",KBD_pagedown);
AddKeyButtonEvent(PX(XO+1),PY(YO+4),BW,BH,"\x18","up",KBD_up);
AddKeyButtonEvent(PX(XO+0),PY(YO+5),BW,BH,"\x1B","left",KBD_left);
AddKeyButtonEvent(PX(XO+1),PY(YO+5),BW,BH,"\x19","down",KBD_down);
AddKeyButtonEvent(PX(XO+2),PY(YO+5),BW,BH,"\x1A","right",KBD_right);
#undef XO
#undef YO
#define XO 0
#define YO 7
/* Numeric KeyPad */
num_lock_event=AddKeyButtonEvent(PX(4),PY(7),BW,BH,"NUM","numlock",KBD_numlock);
AddKeyButtonEvent(PX(5),PY(7),BW,BH,"/","kp_divide",KBD_kpdivide);
AddKeyButtonEvent(PX(6),PY(7),BW,BH,"*","kp_multiply",KBD_kpmultiply);
AddKeyButtonEvent(PX(7),PY(7),BW,BH,"-","kp_minus",KBD_kpminus);
AddKeyButtonEvent(PX(4),PY(8),BW,BH,"7","kp_7",KBD_kp7);
AddKeyButtonEvent(PX(5),PY(8),BW,BH,"8","kp_8",KBD_kp8);
AddKeyButtonEvent(PX(6),PY(8),BW,BH,"9","kp_9",KBD_kp9);
AddKeyButtonEvent(PX(7),PY(8),BW,BH*2,"+","kp_plus",KBD_kpplus);
AddKeyButtonEvent(PX(4),PY(9),BW,BH,"4","kp_4",KBD_kp4);
AddKeyButtonEvent(PX(5),PY(9),BW,BH,"5","kp_5",KBD_kp5);
AddKeyButtonEvent(PX(6),PY(9),BW,BH,"6","kp_6",KBD_kp6);
AddKeyButtonEvent(PX(4),PY(10),BW,BH,"1","kp_1",KBD_kp1);
AddKeyButtonEvent(PX(5),PY(10),BW,BH,"2","kp_2",KBD_kp2);
AddKeyButtonEvent(PX(6),PY(10),BW,BH,"3","kp_3",KBD_kp3);
AddKeyButtonEvent(PX(7),PY(10),BW,BH*2,"ENT","kp_enter",KBD_kpenter);
AddKeyButtonEvent(PX(4),PY(11),BW*2,BH,"0","kp_0",KBD_kp0);
AddKeyButtonEvent(PX(6),PY(11),BW,BH,".","kp_period",KBD_kpperiod);
num_lock_event=AddKeyButtonEvent(PX(XO),PY(YO),BW,BH,"NUM","numlock",KBD_numlock);
AddKeyButtonEvent(PX(XO+1),PY(YO),BW,BH,"/","kp_divide",KBD_kpdivide);
AddKeyButtonEvent(PX(XO+2),PY(YO),BW,BH,"*","kp_multiply",KBD_kpmultiply);
AddKeyButtonEvent(PX(XO+3),PY(YO),BW,BH,"-","kp_minus",KBD_kpminus);
AddKeyButtonEvent(PX(XO+0),PY(YO+1),BW,BH,"7","kp_7",KBD_kp7);
AddKeyButtonEvent(PX(XO+1),PY(YO+1),BW,BH,"8","kp_8",KBD_kp8);
AddKeyButtonEvent(PX(XO+2),PY(YO+1),BW,BH,"9","kp_9",KBD_kp9);
AddKeyButtonEvent(PX(XO+3),PY(YO+1),BW,BH*2,"+","kp_plus",KBD_kpplus);
AddKeyButtonEvent(PX(XO),PY(YO+2),BW,BH,"4","kp_4",KBD_kp4);
AddKeyButtonEvent(PX(XO+1),PY(YO+2),BW,BH,"5","kp_5",KBD_kp5);
AddKeyButtonEvent(PX(XO+2),PY(YO+2),BW,BH,"6","kp_6",KBD_kp6);
AddKeyButtonEvent(PX(XO+0),PY(YO+3),BW,BH,"1","kp_1",KBD_kp1);
AddKeyButtonEvent(PX(XO+1),PY(YO+3),BW,BH,"2","kp_2",KBD_kp2);
AddKeyButtonEvent(PX(XO+2),PY(YO+3),BW,BH,"3","kp_3",KBD_kp3);
AddKeyButtonEvent(PX(XO+3),PY(YO+3),BW,BH*2,"ENT","kp_enter",KBD_kpenter);
AddKeyButtonEvent(PX(XO),PY(YO+4),BW*2,BH,"0","kp_0",KBD_kp0);
AddKeyButtonEvent(PX(XO+2),PY(YO+4),BW,BH,".","kp_period",KBD_kpperiod);
#undef XO
#undef YO
#define XO 10
#define YO 8
/* Joystick Buttons/Texts */
/* Buttons 1+2 of 1st Joystick */
AddJButtonButton(PX(18),PY(0),BW,BH,"1" ,0,0);
AddJButtonButton(PX(20),PY(0),BW,BH,"2" ,0,1);
AddJButtonButton(PX(XO),PY(YO),BW,BH,"1" ,0,0);
AddJButtonButton(PX(XO+2),PY(YO),BW,BH,"2" ,0,1);
/* Axes 1+2 (X+Y) of 1st Joystick */
CJAxisEvent * cjaxis=AddJAxisButton(PX(19),PY(0),BW,BH,"Y-",0,1,false,NULL);
AddJAxisButton (PX(19),PY(1),BW,BH,"Y+",0,1,true,cjaxis);
cjaxis=AddJAxisButton (PX(18),PY(1),BW,BH,"X-",0,0,false,NULL);
AddJAxisButton (PX(20),PY(1),BW,BH,"X+",0,0,true,cjaxis);
CJAxisEvent * cjaxis=AddJAxisButton(PX(XO+1),PY(YO),BW,BH,"Y-",0,1,false,NULL);
AddJAxisButton (PX(XO+1),PY(YO+1),BW,BH,"Y+",0,1,true,cjaxis);
cjaxis=AddJAxisButton (PX(XO),PY(YO+1),BW,BH,"X-",0,0,false,NULL);
AddJAxisButton (PX(XO+2),PY(YO+1),BW,BH,"X+",0,0,true,cjaxis);
if (joytype==JOY_2AXIS) {
/* Buttons 1+2 of 2nd Joystick */
AddJButtonButton(PX(18),PY(3),BW,BH,"1" ,1,0);
AddJButtonButton(PX(20),PY(3),BW,BH,"2" ,1,1);
AddJButtonButton(PX(XO+4),PY(YO),BW,BH,"1" ,1,0);
AddJButtonButton(PX(XO+4+2),PY(YO),BW,BH,"2" ,1,1);
/* Buttons 3+4 of 1st Joystick, not accessible */
AddJButtonButton_hidden(0,2);
AddJButtonButton_hidden(0,3);
/* Axes 1+2 (X+Y) of 2nd Joystick */
cjaxis= AddJAxisButton(PX(18),PY(4),BW,BH,"X-",1,0,false,NULL);
AddJAxisButton(PX(20),PY(4),BW,BH,"X+",1,0,true,cjaxis);
cjaxis= AddJAxisButton(PX(19),PY(3),BW,BH,"Y-",1,1,false,NULL);
AddJAxisButton(PX(19),PY(4),BW,BH,"Y+",1,1,true,cjaxis);
cjaxis= AddJAxisButton(PX(XO+4),PY(YO+1),BW,BH,"X-",1,0,false,NULL);
AddJAxisButton(PX(XO+4+2),PY(YO+1),BW,BH,"X+",1,0,true,cjaxis);
cjaxis= AddJAxisButton(PX(XO+4+1),PY(YO+0),BW,BH,"Y-",1,1,false,NULL);
AddJAxisButton(PX(XO+4+1),PY(YO+1),BW,BH,"Y+",1,1,true,cjaxis);
/* Axes 3+4 (X+Y) of 1st Joystick, not accessible */
cjaxis= AddJAxisButton_hidden(0,2,false,NULL);
AddJAxisButton_hidden(0,2,true,cjaxis);
@ -1864,17 +1873,17 @@ static void CreateLayout(void) {
AddJAxisButton_hidden(0,3,true,cjaxis);
} else {
/* Buttons 3+4 of 1st Joystick */
AddJButtonButton(PX(18),PY(3),BW,BH,"3" ,0,2);
AddJButtonButton(PX(20),PY(3),BW,BH,"4" ,0,3);
AddJButtonButton(PX(XO+4),PY(YO),BW,BH,"3" ,0,2);
AddJButtonButton(PX(XO+4+2),PY(YO),BW,BH,"4" ,0,3);
/* Buttons 1+2 of 2nd Joystick, not accessible */
AddJButtonButton_hidden(1,0);
AddJButtonButton_hidden(1,1);
/* Axes 3+4 (X+Y) of 1st Joystick */
cjaxis= AddJAxisButton(PX(18),PY(4),BW,BH,"X-",0,2,false,NULL);
AddJAxisButton(PX(20),PY(4),BW,BH,"X+",0,2,true,cjaxis);
cjaxis= AddJAxisButton(PX(19),PY(3),BW,BH,"Y-",0,3,false,NULL);
AddJAxisButton(PX(19),PY(4),BW,BH,"Y+",0,3,true,cjaxis);
cjaxis= AddJAxisButton(PX(XO+4),PY(YO+1),BW,BH,"X-",0,2,false,NULL);
AddJAxisButton(PX(XO+4+2),PY(YO+1),BW,BH,"X+",0,2,true,cjaxis);
cjaxis= AddJAxisButton(PX(XO+4+1),PY(YO+0),BW,BH,"Y-",0,3,false,NULL);
AddJAxisButton(PX(XO+4+1),PY(YO+1),BW,BH,"Y+",0,3,true,cjaxis);
/* Axes 1+2 (X+Y) of 2nd Joystick , not accessible*/
cjaxis= AddJAxisButton_hidden(1,0,false,NULL);
AddJAxisButton_hidden(1,0,true,cjaxis);
@ -1884,8 +1893,8 @@ static void CreateLayout(void) {
if (joytype==JOY_CH) {
/* Buttons 5+6 of 1st Joystick */
AddJButtonButton(PX(18),PY(6),BW,BH,"5" ,0,4);
AddJButtonButton(PX(20),PY(6),BW,BH,"6" ,0,5);
AddJButtonButton(PX(XO+8),PY(YO),BW,BH,"5" ,0,4);
AddJButtonButton(PX(XO+8+2),PY(YO),BW,BH,"6" ,0,5);
} else {
/* Buttons 5+6 of 1st Joystick, not accessible */
AddJButtonButton_hidden(0,4);
@ -1893,17 +1902,42 @@ static void CreateLayout(void) {
}
/* Hat directions up, left, down, right */
AddJHatButton(PX(19),PY(6),BW,BH,"UP",0,0,0);
AddJHatButton(PX(18),PY(7),BW,BH,"LFT",0,0,3);
AddJHatButton(PX(19),PY(7),BW,BH,"DWN",0,0,2);
AddJHatButton(PX(20),PY(7),BW,BH,"RGT",0,0,1);
AddJHatButton(PX(XO+8+1),PY(YO),BW,BH,"UP",0,0,0);
AddJHatButton(PX(XO+8+0),PY(YO+1),BW,BH,"LFT",0,0,3);
AddJHatButton(PX(XO+8+1),PY(YO+1),BW,BH,"DWN",0,0,2);
AddJHatButton(PX(XO+8+2),PY(YO+1),BW,BH,"RGT",0,0,1);
/* Labels for the joystick */
if (joytype ==JOY_2AXIS) {
new CTextButton(PX(XO+0),PY(YO-1),3*BW,20,"Joystick 1");
new CTextButton(PX(XO+4),PY(YO-1),3*BW,20,"Joystick 2");
new CTextButton(PX(XO+8),PY(YO-1),3*BW,20,"Disabled");
} else if(joytype ==JOY_4AXIS || joytype == JOY_4AXIS_2) {
new CTextButton(PX(XO+0),PY(YO-1),3*BW,20,"Axis 1/2");
new CTextButton(PX(XO+4),PY(YO-1),3*BW,20,"Axis 3/4");
new CTextButton(PX(XO+8),PY(YO-1),3*BW,20,"Disabled");
} else if(joytype == JOY_CH) {
new CTextButton(PX(XO+0),PY(YO-1),3*BW,20,"Axis 1/2");
new CTextButton(PX(XO+4),PY(YO-1),3*BW,20,"Axis 3/4");
new CTextButton(PX(XO+8),PY(YO-1),3*BW,20,"Hat/D-pad");
} else if ( joytype==JOY_FCS) {
new CTextButton(PX(XO+0),PY(YO-1),3*BW,20,"Axis 1/2");
new CTextButton(PX(XO+4),PY(YO-1),3*BW,20,"Axis 3");
new CTextButton(PX(XO+8),PY(YO-1),3*BW,20,"Hat/D-pad");
} else if(joytype == JOY_NONE) {
new CTextButton(PX(XO+0),PY(YO-1),3*BW,20,"Disabled");
new CTextButton(PX(XO+4),PY(YO-1),3*BW,20,"Disabled");
new CTextButton(PX(XO+8),PY(YO-1),3*BW,20,"Disabled");
}
/* The modifier buttons */
AddModButton(PX(0),PY(13),50,20,"Mod1",1);
AddModButton(PX(2),PY(13),50,20,"Mod2",2);
AddModButton(PX(4),PY(13),50,20,"Mod3",3);
AddModButton(PX(0),PY(14),50,20,"Mod1",1);
AddModButton(PX(2),PY(14),50,20,"Mod2",2);
AddModButton(PX(4),PY(14),50,20,"Mod3",3);
/* Create Handler buttons */
Bitu xpos=3;Bitu ypos=10;
Bitu xpos=3;Bitu ypos=11;
for (CHandlerEventVector_it hit=handlergroup.begin();hit!=handlergroup.end();hit++) {
new CEventButton(PX(xpos*3),PY(ypos),BW*3,BH,(*hit)->ButtonName(),(*hit));
xpos++;
@ -1912,8 +1946,8 @@ static void CreateLayout(void) {
}
}
/* Create some text buttons */
new CTextButton(PX(6),0,124,20,"Keyboard Layout");
new CTextButton(PX(17),0,124,20,"Joystick Layout");
// new CTextButton(PX(6),0,124,20,"Keyboard Layout");
// new CTextButton(PX(17),0,124,20,"Joystick Layout");
bind_but.action=new CCaptionButton(180,330,0,0);
@ -2083,7 +2117,7 @@ void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char const
}
static void MAPPER_SaveBinds(void) {
FILE * savefile=fopen(mapper.filename.c_str(),"wb+");
FILE * savefile=fopen(mapper.filename.c_str(),"wt+");
if (!savefile) {
LOG_MSG("Can't open %s for saving the mappings",mapper.filename.c_str());
return;
@ -2105,7 +2139,7 @@ static void MAPPER_SaveBinds(void) {
}
static bool MAPPER_LoadBinds(void) {
FILE * loadfile=fopen(mapper.filename.c_str(),"rb");
FILE * loadfile=fopen(mapper.filename.c_str(),"rt");
if (!loadfile) return false;
char linein[512];
while (fgets(linein,512,loadfile)) {
@ -2326,11 +2360,17 @@ void MAPPER_Init(void) {
if (SDL_GetModState()&KMOD_CAPS) {
for (CBindList_it bit=caps_lock_event->bindlist.begin();bit!=caps_lock_event->bindlist.end();bit++) {
(*bit)->ActivateBind(32767,true,true);
#if SDL_VERSION_ATLEAST(1, 2, 14)
(*bit)->DeActivateBind(false);
#endif
}
}
if (SDL_GetModState()&KMOD_NUM) {
for (CBindList_it bit=num_lock_event->bindlist.begin();bit!=num_lock_event->bindlist.end();bit++) {
(*bit)->ActivateBind(32767,true,true);
#if SDL_VERSION_ATLEAST(1, 2, 14)
(*bit)->DeActivateBind(false);
#endif
}
}
}

View File

@ -54,6 +54,7 @@
#include "cross.h"
#include "control.h"
#define MAPPERFILE "mapper-" VERSION ".map"
//#define DISABLE_JOYSTICK
#if C_OPENGL
@ -238,12 +239,9 @@ void GFX_SetTitle(Bit32s cycles,Bits frameskip,bool paused){
if(cycles != -1) internal_cycles = cycles;
if(frameskip != -1) internal_frameskip = frameskip;
if(CPU_CycleAutoAdjust) {
if (internal_cycles>=100)
sprintf(title,"DOSBox %s, Cpu Cycles: max, Frameskip %2d, Program: %8s",VERSION,internal_frameskip,RunningProgram);
else
sprintf(title,"DOSBox %s, Cpu Cycles: [%3d%%], Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram);
sprintf(title,"DOSBox %s, Cpu speed: max %3d%% cycles, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram);
} else {
sprintf(title,"DOSBox %s, Cpu Cycles: %8d, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram);
sprintf(title,"DOSBox %s, Cpu speed: %8d cycles, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram);
}
if(paused) strcat(title," PAUSED");
@ -1505,13 +1503,16 @@ void Config_Add_SDL() {
#else
Pbool = sdl_sec->Add_bool("fulldouble",Property::Changeable::Always,false);
#endif
Pbool->Set_help("Use double buffering in fullscreen.");
Pbool->Set_help("Use double buffering in fullscreen. It can reduce screen flickering, but it can also result in a slow DOSBox.");
Pstring = sdl_sec->Add_string("fullresolution",Property::Changeable::Always,"original");
Pstring->Set_help("What resolution to use for fullscreen: original or fixed size (e.g. 1024x768).");
Pstring->Set_help("What resolution to use for fullscreen: original or fixed size (e.g. 1024x768).\n"
" Using your monitor's native resolution with aspect=true might give the best results.\n"
" If you end up with small window on a large screen, try an output different from surface.");
Pstring = sdl_sec->Add_string("windowresolution",Property::Changeable::Always,"original");
Pstring->Set_help("Scale the window to this size IF the output device supports hardware scaling.");
Pstring->Set_help("Scale the window to this size IF the output device supports hardware scaling.\n"
" (output=surface does not!)");
const char* outputs[] = {
"surface", "overlay",
@ -1527,7 +1528,7 @@ void Config_Add_SDL() {
Pstring->Set_values(outputs);
Pbool = sdl_sec->Add_bool("autolock",Property::Changeable::Always,true);
Pbool->Set_help("Mouse will automatically lock, if you click on the screen.");
Pbool->Set_help("Mouse will automatically lock, if you click on the screen. (Press CTRL-F10 to unlock)");
Pint = sdl_sec->Add_int("sensitivity",Property::Changeable::Always,100);
Pint->SetMinMax(1,1000);
@ -1538,7 +1539,8 @@ void Config_Add_SDL() {
Pmulti = sdl_sec->Add_multi("priority", Property::Changeable::Always, ",");
Pmulti->SetValue("higher,normal");
Pmulti->Set_help("Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized. (pause is only valid for the second entry)");
Pmulti->Set_help("Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized.\n"
" pause is only valid for the second entry.");
const char* actt[] = { "lowest", "lower", "normal", "higher", "highest", "pause", 0};
Pstring = Pmulti->GetSection()->Add_string("active",Property::Changeable::Always,"higher");
@ -1548,8 +1550,8 @@ void Config_Add_SDL() {
Pstring = Pmulti->GetSection()->Add_string("inactive",Property::Changeable::Always,"normal");
Pstring->Set_values(inactt);
Pstring = sdl_sec->Add_path("mapperfile",Property::Changeable::Always,"mapper.conf");
Pstring->Set_help("File used to load/save the key/event mappings from.");
Pstring = sdl_sec->Add_path("mapperfile",Property::Changeable::Always,MAPPERFILE);
Pstring->Set_help("File used to load/save the key/event mappings from. Resetmapper only works with the defaul value.");
Pbool = sdl_sec->Add_bool("usescancodes",Property::Changeable::Always,true);
Pbool->Set_help("Avoid usage of symkeys, might not work on all operating systems.");
@ -1594,7 +1596,7 @@ static void show_warning(char const * const message) {
SDL_BlitSurface(splash_surf, NULL, sdl.surface, NULL);
SDL_Flip(sdl.surface);
SDL_Delay(10000);
SDL_Delay(12000);
}
static void launcheditor() {
@ -1666,7 +1668,7 @@ static void eraseconfigfile() {
FILE* f = fopen("dosbox.conf","r");
if(f) {
fclose(f);
//show_warning("Warning: dosbox.conf exists in current working directory.\nThis will override the configuration file at runtime.\n");
show_warning("Warning: dosbox.conf exists in current working directory.\nThis will override the configuration file at runtime.\n");
}
std::string path,file;
Cross::GetPlatformConfigDir(path);
@ -1679,7 +1681,27 @@ static void eraseconfigfile() {
exit(0);
}
static void erasemapperfile() {
FILE* g = fopen("dosbox.conf","r");
if(g) {
fclose(g);
show_warning("Warning: dosbox.conf exists in current working directory.\nKeymapping might not be properly reset.\n"
"Please reset configuration as well and delete the dosbox.conf.\n");
}
std::string path,file=MAPPERFILE;
Cross::GetPlatformConfigDir(path);
path += file;
FILE* f = fopen(path.c_str(),"r");
if(!f) exit(0);
fclose(f);
unlink(path.c_str());
exit(0);
}
#ifdef HW_RVL
int MountDOSBoxDir(char DriveLetter, const char *path);
#endif
//extern void UI_Init(void);
int main(int argc, char* argv[]) {
@ -1700,6 +1722,9 @@ int main(int argc, char* argv[]) {
if(control->cmdline->FindString("-editconf",editor,false)) launcheditor();
if(control->cmdline->FindString("-opencaptures",editor,true)) launchcaptures(editor);
if(control->cmdline->FindExist("-eraseconf")) eraseconfigfile();
if(control->cmdline->FindExist("-resetconf")) eraseconfigfile();
if(control->cmdline->FindExist("-erasemapper")) erasemapperfile();
if(control->cmdline->FindExist("-resetmapper")) erasemapperfile();
/* Can't disable the console with debugger enabled */
#if defined(WIN32) && !(C_DEBUG)
@ -1808,7 +1833,28 @@ int main(int argc, char* argv[]) {
/* Parse configuration files */
std::string config_file,config_path;
bool parsed_anyconfigfile = false;
//First Parse -conf switches
//First Parse -userconf
if(control->cmdline->FindExist("-userconf",true)){
config_file.clear();
Cross::GetPlatformConfigDir(config_path);
Cross::GetPlatformConfigName(config_file);
config_path += config_file;
if(control->ParseConfigFile(config_path.c_str())) parsed_anyconfigfile = true;
if(!parsed_anyconfigfile) {
//Try to create the userlevel configfile.
config_file.clear();
Cross::CreatePlatformConfigDir(config_path);
Cross::GetPlatformConfigName(config_file);
config_path += config_file;
if(control->PrintConfig(config_path.c_str())) {
LOG_MSG("CONFIG: Generating default configuration.\nWriting it to %s",config_path.c_str());
//Load them as well. Makes relative paths much easier
if(control->ParseConfigFile(config_path.c_str())) parsed_anyconfigfile = true;
}
}
}
//Second parse -conf entries
while(control->cmdline->FindString("-conf",config_file,true))
if (control->ParseConfigFile(config_file.c_str())) parsed_anyconfigfile = true;

View File

@ -619,6 +619,7 @@ Operator::Operator() {
currentLevel = ENV_MAX;
totalLevel = ENV_MAX;
volume = ENV_MAX;
releaseAdd = 0;
}
/*
@ -1176,9 +1177,7 @@ Bit32u Chip::WriteAddr( Bit32u port, Bit8u val ) {
void Chip::GenerateBlock2( Bitu total, Bit32s* output ) {
while ( total > 0 ) {
Bit32u samples = ForwardLFO( total );
for ( Bitu i = 0; i < samples; i++ ) {
output[i] = 0;
}
memset(output, 0, sizeof(Bit32s) * samples);
int count = 0;
for( Channel* ch = chan; ch < chan + 9; ) {
count++;
@ -1192,10 +1191,7 @@ void Chip::GenerateBlock2( Bitu total, Bit32s* output ) {
void Chip::GenerateBlock3( Bitu total, Bit32s* output ) {
while ( total > 0 ) {
Bit32u samples = ForwardLFO( total );
for ( Bitu i = 0; i < samples; i++ ) {
output[i * 2 + 0 ] = 0;
output[i * 2 + 1 ] = 0;
}
memset(output, 0, sizeof(Bit32s) * samples *2);
int count = 0;
for( Channel* ch = chan; ch < chan + 18; ) {
count++;

View File

@ -80,7 +80,7 @@ struct SAA1099
struct saa1099_noise noise[2]; /* noise generators */
};
static UINT8 envelope[8][64] = {
static const UINT8 envelope[8][64] = {
/* zero amplitude */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -124,7 +124,7 @@ static UINT8 envelope[8][64] = {
};
static int amplitude_lookup[16] = {
static const int amplitude_lookup[16] = {
0*32767/16, 1*32767/16, 2*32767/16, 3*32767/16,
4*32767/16, 5*32767/16, 6*32767/16, 7*32767/16,
8*32767/16, 9*32767/16, 10*32767/16, 11*32767/16,

View File

@ -652,6 +652,8 @@ void MIXER_Init(Section* sec) {
mixer.tick_add=((mixer.freq) << MIXER_SHIFT)/1000;
TIMER_AddTickHandler(MIXER_Mix_NoSound);
} else {
if((mixer.freq != obtained.freq) || (mixer.blocksize != obtained.samples))
LOG_MSG("MIXER:Got different values from SDL: freq %d, blocksize %d",obtained.freq,obtained.samples);
mixer.freq=obtained.freq;
mixer.blocksize=obtained.samples;
mixer.tick_add=(mixer.freq << MIXER_SHIFT)/1000;

View File

@ -1469,6 +1469,7 @@ private:
IO_WriteHandleObject WriteHandler[0x10];
AutoexecObject autoexecline;
MixerObject MixerChan;
OPL_Mode oplmode;
/* Support Functions */
void Find_Type_And_Opl(Section_prop* config,SB_TYPES& type, OPL_Mode& opl_mode){
@ -1497,14 +1498,22 @@ private:
else {
switch (type) {
case SBT_NONE:
opl_mode=OPL_none;
break;
case SBT_GB:
opl_mode=OPL_none;break;
case SBT_1:opl_mode=OPL_opl2;break;
case SBT_2:opl_mode=OPL_opl2;break;
case SBT_PRO1:opl_mode=OPL_dualopl2;break;
opl_mode=OPL_cms;
break;
case SBT_1:
case SBT_2:
opl_mode=OPL_opl2;
break;
case SBT_PRO1:
opl_mode=OPL_dualopl2;
break;
case SBT_PRO2:
case SBT_16:
opl_mode=OPL_opl3;break;
opl_mode=OPL_opl3;
break;
}
}
}
@ -1524,27 +1533,25 @@ public:
sb.mixer.enabled=section->Get_bool("sbmixer");
sb.mixer.stereo=false;
OPL_Mode opl_mode = OPL_none;
Find_Type_And_Opl(section,sb.type,opl_mode);
bool do_cms = (sb.type==SBT_GB)? true:false;
switch (opl_mode) {
Find_Type_And_Opl(section,sb.type,oplmode);
switch (oplmode) {
case OPL_none:
WriteHandler[0].Install(0x388,adlib_gusforward,IO_MB);
break;
case OPL_cms:
WriteHandler[0].Install(0x388,adlib_gusforward,IO_MB);
do_cms = true;
CMS_Init(section);
break;
case OPL_opl2:
do_cms = true;
CMS_Init(section);
// fall-through
case OPL_dualopl2:
case OPL_opl3:
OPL_Init(section,opl_mode);
OPL_Init(section,oplmode);
break;
}
if (do_cms) CMS_Init(section);
if (sb.type==SBT_NONE || sb.type==SBT_GB) return;
sb.chan=MixerChan.Install(&SBLASTER_CallBack,22050,"SB");
@ -1588,28 +1595,22 @@ public:
}
~SBLASTER() {
Section_prop * section=static_cast<Section_prop *>(m_configuration);
OPL_Mode opl_mode = OPL_none;
Find_Type_And_Opl(section,sb.type,opl_mode);
switch (opl_mode) {
switch (oplmode) {
case OPL_none:
break;
case OPL_cms:
CMS_ShutDown(m_configuration);
CMS_ShutDown(m_configuration);
break;
case OPL_opl2:
CMS_ShutDown(m_configuration);
CMS_ShutDown(m_configuration);
// fall-through
case OPL_dualopl2:
case OPL_opl3:
OPL_ShutDown(m_configuration);
OPL_ShutDown(m_configuration);
break;
}
if (sb.type==SBT_NONE || sb.type==SBT_GB) return;
DSP_Reset();//Stop everything
DSP_Reset(); // Stop everything
}
}; //End of SBLASTER class

View File

@ -41,6 +41,12 @@ Bit32u Expand16Table[4][16];
Bit32u FillTable[16];
Bit32u ColorTable[16];
void VGA_SetModeNow(VGAModes mode) {
if (vga.mode == mode) return;
vga.mode=mode;
VGA_SetupHandlers();
VGA_StartResize(0);
}
void VGA_SetMode(VGAModes mode) {
@ -85,8 +91,10 @@ void VGA_DetermineMode(void) {
void VGA_StartResize(Bitu delay /*=50*/) {
if (!vga.draw.resizing) {
vga.draw.resizing=true;
if (vga.mode==M_ERROR) delay = 5;
/* Start a resize after delay (default 50 ms) */
PIC_AddEvent(VGA_SetupDrawing,(float)delay);
if (delay==0) VGA_SetupDrawing(0);
else PIC_AddEvent(VGA_SetupDrawing,(float)delay);
}
}
@ -167,8 +175,6 @@ void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3) {
void VGA_Init(Section* sec) {
// Section_prop * section=static_cast<Section_prop *>(sec);
// vga.screenflip = section->Get_int("screenflip");
vga.screenflip = 0;
vga.draw.resizing=false;
vga.mode=M_ERROR; //For first init
SVGA_Setup_Driver();

View File

@ -46,7 +46,7 @@ void VGA_ATTR_SetPalette(Bit8u index,Bit8u val) {
Bitu read_p3c0(Bitu /*port*/,Bitu /*iolen*/) {
// Wcharts, Win 3.11 & 95 SVGA
Bitu retval = attr(index) & 0x1f;
if (attr(enabled)) retval |= 0x20;
if (!(attr(disabled) & 0x1)) retval |= 0x20;
return retval;
}
@ -54,7 +54,8 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) {
if (!vga.internal.attrindex) {
attr(index)=val & 0x1F;
vga.internal.attrindex=true;
attr(enabled)=val & 0x20;
if (val & 0x20) attr(disabled) &= ~1;
else attr(disabled) |= 1;
/*
0-4 Address of data register to write to port 3C0h or read from port 3C1h
5 If set screen output is enabled and the palette can not be modified,
@ -69,7 +70,7 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) {
case 0x04: case 0x05: case 0x06: case 0x07:
case 0x08: case 0x09: case 0x0a: case 0x0b:
case 0x0c: case 0x0d: case 0x0e: case 0x0f:
if (!attr(enabled)) VGA_ATTR_SetPalette(attr(index),(Bit8u)val);
if (attr(disabled) & 0x1) VGA_ATTR_SetPalette(attr(index),(Bit8u)val);
/*
0-5 Index into the 256 color DAC table. May be modified by 3C0h index
10h and 14h.

View File

@ -27,6 +27,10 @@
#include "vga.h"
#include "pic.h"
//#undef C_DEBUG
//#define C_DEBUG 1
//#define LOG(X,Y) LOG_MSG
#define VGA_PARTS 4
typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart, Bitu line);
@ -637,15 +641,13 @@ static void VGA_ProcessSplit() {
}
static void VGA_DrawSingleLine(Bitu /*blah*/) {
if (vga.attr.enabled) {
Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line );
RENDER_DrawLine(data);
} else {
// else draw overscan color line
// TODO: black line should be good enough for now
// (DoWhackaDo)
if (GCC_UNLIKELY(vga.attr.disabled)) {
// draw blanked line (DoWhackaDo, Alien Carnage, TV sports Football)
memset(TempLine, 0, sizeof(TempLine));
RENDER_DrawLine(TempLine);
} else {
Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line );
RENDER_DrawLine(data);
}
vga.draw.address_line++;
@ -657,7 +659,7 @@ static void VGA_DrawSingleLine(Bitu /*blah*/) {
if (vga.draw.split_line==vga.draw.lines_done) VGA_ProcessSplit();
if (vga.draw.lines_done < vga.draw.lines_total) {
PIC_AddEvent(VGA_DrawSingleLine,(float)vga.draw.delay.htotal);
} else RENDER_EndUpdate();
} else RENDER_EndUpdate(false);
}
static void VGA_DrawPart(Bitu lines) {
@ -687,7 +689,7 @@ static void VGA_DrawPart(Bitu lines) {
#ifdef VGA_KEEP_CHANGES
VGA_ChangesEnd();
#endif
RENDER_EndUpdate();
RENDER_EndUpdate(false);
}
}
@ -736,6 +738,11 @@ static void VGA_VertInterrupt(Bitu /*val*/) {
}
}
static void VGA_Other_VertInterrupt(Bitu val) {
if (val) PIC_ActivateIRQ(5);
else PIC_DeActivateIRQ(5);
}
static void VGA_DisplayStartLatch(Bitu /*val*/) {
vga.config.real_start=vga.config.display_start & (vga.vmemwrap-1);
vga.draw.bytes_skip = vga.config.bytes_skip;
@ -746,43 +753,40 @@ static void VGA_PanningLatch(Bitu /*val*/) {
}
static void VGA_VerticalTimer(Bitu /*val*/) {
double error = vga.draw.delay.framestart;
vga.draw.delay.framestart = PIC_FullIndex();
error = vga.draw.delay.framestart - error - vga.draw.delay.vtotal;
PIC_AddEvent( VGA_VerticalTimer, (float)vga.draw.delay.vtotal );
//PIC_AddEvent( VGA_VerticalDisplayEnd, (float)vga.draw.delay.vrstart );
double flip_offset = vga.screenflip/1000.0 + vga.draw.delay.vrstart;
if(flip_offset > vga.draw.delay.vtotal) {
switch(machine) {
case MCH_PCJR:
case MCH_TANDY:
// PCJr: Vsync is directly connected to the IRQ controller
// Some earlier Tandy models are said to have a vsync interrupt too
PIC_AddEvent(VGA_Other_VertInterrupt, (float)vga.draw.delay.vrstart, 1);
PIC_AddEvent(VGA_Other_VertInterrupt, (float)vga.draw.delay.vrend, 0);
// fall-through
case MCH_CGA:
case MCH_HERC:
// MC6845-powered graphics: Loading the display start latch happens somewhere
// after vsync off and before first visible scanline, so probably here
VGA_DisplayStartLatch(0);
} else PIC_AddEvent( VGA_DisplayStartLatch,(float)flip_offset);
PIC_AddEvent(VGA_PanningLatch,(float)vga.draw.delay.vrend);
// EGA: 82c435 datasheet: interrupt happens at display end
// VGA: checked with scope
// add a little amount of time to make sure the last drawpart has already fired
if (IS_EGAVGA_ARCH) PIC_AddEvent(VGA_VertInterrupt,(float)(vga.draw.delay.vdend + 0.005));
if ( GCC_UNLIKELY( vga.draw.parts_left)) {
if (!IS_VGA_ARCH || (svgaCard!=SVGA_None)) {
LOG(LOG_VGAMISC,LOG_NORMAL)( "Parts left: %d", vga.draw.parts_left );
PIC_RemoveEvents( &VGA_DrawPart );
RENDER_EndUpdate();
vga.draw.parts_left = 0;
}
break;
case MCH_VGA:
case MCH_EGA:
PIC_AddEvent(VGA_DisplayStartLatch, (float)vga.draw.delay.vrstart);
PIC_AddEvent(VGA_PanningLatch, (float)vga.draw.delay.vrend);
// EGA: 82c435 datasheet: interrupt happens at display end
// VGA: checked with scope; however disabled by default by jumper on VGA boards
// add a little amount of time to make sure the last drawpart has already fired
PIC_AddEvent(VGA_VertInterrupt,(float)(vga.draw.delay.vdend + 0.005));
break;
default:
E_Exit("This new machine needs implementation in VGA_VerticalTimer too.");
break;
}
//Check if we can actually render, else skip the rest
//Check if we can actually render, else skip the rest (frameskip)
if (!RENDER_StartUpdate())
return;
if ( GCC_UNLIKELY( vga.draw.lines_done < vga.draw.lines_total)) {
if (IS_VGA_ARCH && (svgaCard==SVGA_None)) {
while(vga.draw.lines_done < vga.draw.lines_total)
VGA_DrawSingleLine(0);
PIC_RemoveEvents(VGA_DrawSingleLine);
}
}
//TODO Maybe check for an active frame on parts_left and clear that first?
vga.draw.parts_left = vga.draw.parts_total;
vga.draw.lines_done = 0;
vga.draw.address_line = vga.config.hlines_skip;
if (IS_EGAVGA_ARCH) {
vga.draw.split_line = (Bitu)((vga.config.line_compare+1)/vga.draw.lines_scaled);
@ -864,17 +868,38 @@ static void VGA_VerticalTimer(Bitu /*val*/) {
#ifdef VGA_KEEP_CHANGES
if (startaddr_changed) VGA_ChangesStart();
#endif
// check if some lines at the top off the screen are blanked
float draw_skip = 0.0;
if (GCC_UNLIKELY(vga.draw.vblank_skip)) {
draw_skip = (float)(vga.draw.delay.htotal * vga.draw.vblank_skip);
vga.draw.address += vga.draw.address_add * (vga.draw.vblank_skip/(vga.draw.address_line_total));
}
if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) PIC_AddEvent(VGA_DrawSingleLine,(float)(vga.draw.delay.htotal/4.0 + draw_skip));
else PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts + draw_skip,vga.draw.parts_lines);
//VGA_DrawPart( vga.draw.parts_lines );
//PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts,vga.draw.parts_lines);
//PIC_AddEvent(VGA_DrawPart,(float)(vga.draw.delay.parts/2),vga.draw.parts_lines); //Else tearline in Tyrian and second reality
// add the draw event
switch (vga.draw.mode) {
case PART:
if (GCC_UNLIKELY(vga.draw.parts_left)) {
LOG(LOG_VGAMISC,LOG_NORMAL)( "Parts left: %d", vga.draw.parts_left );
PIC_RemoveEvents(VGA_DrawPart);
RENDER_EndUpdate(true);
}
vga.draw.lines_done = 0;
vga.draw.parts_left = vga.draw.parts_total;
PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts + draw_skip,vga.draw.parts_lines);
break;
case LINE:
if (GCC_UNLIKELY(vga.draw.lines_done < vga.draw.lines_total)) {
LOG(LOG_VGAMISC,LOG_NORMAL)( "Lines left: %d",
vga.draw.lines_total-vga.draw.lines_done);
PIC_RemoveEvents(VGA_DrawSingleLine);
RENDER_EndUpdate(true);
}
vga.draw.lines_done = 0;
PIC_AddEvent(VGA_DrawSingleLine,(float)(vga.draw.delay.htotal/4.0 + draw_skip));
break;
//case EGALINE:
}
}
void VGA_CheckScanLength(void) {
@ -951,8 +976,25 @@ void VGA_SetupDrawing(Bitu /*val*/) {
PIC_RemoveEvents(VGA_DisplayStartLatch);
return;
}
// set the drawing mode
switch (machine) {
case MCH_CGA:
case MCH_PCJR:
vga.draw.mode = LINE;
break;
case MCH_VGA:
if (svgaCard==SVGA_None) {
vga.draw.mode = LINE;
break;
}
// fall-through
default:
vga.draw.mode = PART;
break;
}
/* Calculate the FPS for this screen */
float fps; Bitu clock;
double fps; Bitu clock;
Bitu htotal, hdend, hbstart, hbend, hrstart, hrend;
Bitu vtotal, vdend, vbstart, vbend, vrstart, vrend;
Bitu vblank_skip;
@ -1052,17 +1094,13 @@ void VGA_SetupDrawing(Bitu /*val*/) {
hbstart = hdend;
hbend = htotal;
hrstart = vga.other.hsyncp;
hrend = hrstart + (vga.other.syncw & 0xf) ;
hrend = hrstart + vga.other.hsyncw;
vga.draw.address_line_total = vga.other.max_scanline + 1;
vtotal = vga.draw.address_line_total * (vga.other.vtotal+1)+vga.other.vadjust;
vdend = vga.draw.address_line_total * vga.other.vdend;
vrstart = vga.draw.address_line_total * vga.other.vsyncp;
vrend = (vga.other.syncw >> 4);
if (!vrend)
vrend = vrstart + 0xf + 1;
else
vrend = vrstart + vrend;
vrend = vrstart + 16; // vsync width is fixed to 16 lines on the MC6845 TODO Tandy
vbstart = vdend;
vbend = vtotal;
vga.draw.double_scan=false;
@ -1090,16 +1128,16 @@ void VGA_SetupDrawing(Bitu /*val*/) {
if (!htotal) return;
if (!vtotal) return;
fps=(float)clock/(vtotal*htotal);
// The time a complete video frame takes
vga.draw.delay.vtotal = (1000.0 * (double)(vtotal*htotal)) / (double)clock;
// The screen refresh frequency
fps=(double)clock/(vtotal*htotal);
// Horizontal total (that's how long a line takes with whistles and bells)
vga.draw.delay.htotal = htotal*1000.0/clock; //in milliseconds
// Start and End of horizontal blanking
vga.draw.delay.hblkstart = hbstart*1000.0/clock; //in milliseconds
vga.draw.delay.hblkend = hbend*1000.0/clock;
vga.draw.delay.hrstart = 0;
// Start and End of horizontal retrace
vga.draw.delay.hrstart = hrstart*1000.0/clock;
vga.draw.delay.hrend = hrend*1000.0/clock;
// Start and End of vertical blanking
vga.draw.delay.vblkstart = vbstart * vga.draw.delay.htotal;
vga.draw.delay.vblkend = vbend * vga.draw.delay.htotal;
@ -1110,48 +1148,39 @@ void VGA_SetupDrawing(Bitu /*val*/) {
// Vertical blanking tricks
vblank_skip = 0;
if (IS_VGA_ARCH) { // others need more investigation
if (vbend > vtotal) {
// blanking wraps to the start of the screen
vblank_skip = vbend&0x7f;
// on blanking wrap to 0, the first line is not blanked
// this is used by the S3 BIOS and other S3 drivers in some SVGA modes
if((vbend&0x7f)==1) vblank_skip = 0;
// it might also cut some lines off the bottom
if(vbstart < vdend) {
vdend = vbstart;
}
LOG(LOG_VGA,LOG_WARN)("Blanking wrap to line %d", vblank_skip);
} else if (vbstart==1) {
// blanking is used to cut lines at the start of the screen
vblank_skip = vbend;
LOG(LOG_VGA,LOG_WARN)("Upper %d lines of the screen blanked", vblank_skip);
} else if (vbstart < vdend) {
if(vbend < vdend) {
// the game wants a black bar somewhere on the screen
LOG(LOG_VGA,LOG_WARN)("Unsupported blanking: line %d-%d",vbstart,vbend);
} else {
// blanking is used to cut off some lines from the bottom
vdend = vbstart;
if (vbstart < vtotal) { // There will be no blanking at all otherwise
if (vbend > vtotal) {
// blanking wraps to the start of the screen
vblank_skip = vbend&0x7f;
// on blanking wrap to 0, the first line is not blanked
// this is used by the S3 BIOS and other S3 drivers in some SVGA modes
if((vbend&0x7f)==1) vblank_skip = 0;
// it might also cut some lines off the bottom
if(vbstart < vdend) {
vdend = vbstart;
}
LOG(LOG_VGA,LOG_WARN)("Blanking wrap to line %d", vblank_skip);
} else if (vbstart==1) {
// blanking is used to cut lines at the start of the screen
vblank_skip = vbend;
LOG(LOG_VGA,LOG_WARN)("Upper %d lines of the screen blanked", vblank_skip);
} else if (vbstart < vdend) {
if(vbend < vdend) {
// the game wants a black bar somewhere on the screen
LOG(LOG_VGA,LOG_WARN)("Unsupported blanking: line %d-%d",vbstart,vbend);
} else {
// blanking is used to cut off some lines from the bottom
vdend = vbstart;
}
}
vdend -= vblank_skip;
}
vdend -= vblank_skip;
}
// Display end
vga.draw.delay.vdend = vdend * vga.draw.delay.htotal;
#if C_DEBUG
LOG(LOG_VGA,LOG_NORMAL)("h total %2.5f (%3.2fkHz) blank(%02.5f/%02.5f) retrace(%02.5f/%02.5f)",
vga.draw.delay.htotal,(1.0/vga.draw.delay.htotal),
vga.draw.delay.hblkstart,vga.draw.delay.hblkend,
vga.draw.delay.hrstart,vga.draw.delay.hrend);
LOG(LOG_VGA,LOG_NORMAL)("v total %2.5f (%3.2fHz) blank(%02.5f/%02.5f) retrace(%02.5f/%02.5f)",
vga.draw.delay.vtotal,(1000.0/vga.draw.delay.vtotal),
vga.draw.delay.vblkstart,vga.draw.delay.vblkend,
vga.draw.delay.vrstart,vga.draw.delay.vrend);
#endif
vga.draw.parts_total=VGA_PARTS;
/*
6 Horizontal Sync Polarity. Negative if set
@ -1386,6 +1415,7 @@ void VGA_SetupDrawing(Bitu /*val*/) {
}
doubleheight=true;
}
vga.draw.vblank_skip = vblank_skip;
if(!(IS_VGA_ARCH && (svgaCard==SVGA_None) && (vga.mode==M_EGA || vga.mode==M_VGA))) {
//Only check for extra double height in vga modes
@ -1412,21 +1442,44 @@ void VGA_SetupDrawing(Bitu /*val*/) {
}
// LOG_MSG("ht %d vt %d ratio %f", htotal, vtotal, aspect_ratio );
if (( width != vga.draw.width) || (height != vga.draw.height) ||
(aspect_ratio != vga.draw.aspect_ratio) ||
(vga.mode != vga.lastmode)) {
vga.lastmode = vga.mode;
// need to change the vertical timing?
if (fabs(vga.draw.delay.vtotal - 1000.0 / fps) > 0.0001) {
vga.draw.delay.vtotal = 1000.0 / fps;
VGA_KillDrawing();
PIC_RemoveEvents(VGA_Other_VertInterrupt);
PIC_RemoveEvents(VGA_VerticalTimer);
PIC_RemoveEvents(VGA_PanningLatch);
PIC_RemoveEvents(VGA_DisplayStartLatch);
PIC_RemoveEvents(VGA_DrawPart);
PIC_RemoveEvents(VGA_DrawSingleLine);
VGA_VerticalTimer(0);
}
#if C_DEBUG
LOG(LOG_VGA,LOG_NORMAL)("h total %2.5f (%3.2fkHz) blank(%02.5f/%02.5f) retrace(%02.5f/%02.5f)",
vga.draw.delay.htotal,(1.0/vga.draw.delay.htotal),
vga.draw.delay.hblkstart,vga.draw.delay.hblkend,
vga.draw.delay.hrstart,vga.draw.delay.hrend);
LOG(LOG_VGA,LOG_NORMAL)("v total %2.5f (%3.2fHz) blank(%02.5f/%02.5f) retrace(%02.5f/%02.5f)",
vga.draw.delay.vtotal,(1000.0/vga.draw.delay.vtotal),
vga.draw.delay.vblkstart,vga.draw.delay.vblkend,
vga.draw.delay.vrstart,vga.draw.delay.vrend);
#endif
// need to resize the output window?
if ((width != vga.draw.width) ||
(height != vga.draw.height) ||
(vga.draw.doublewidth != doublewidth) ||
(vga.draw.doubleheight != doubleheight) ||
(fabs(aspect_ratio - vga.draw.aspect_ratio) > 0.0001) ||
(vga.draw.bpp != bpp)) {
VGA_KillDrawing();
vga.draw.width = width;
vga.draw.height = height;
vga.draw.doublewidth = doublewidth;
vga.draw.doubleheight = doubleheight;
vga.draw.aspect_ratio = aspect_ratio;
vga.draw.vblank_skip = vblank_skip;
vga.draw.bpp = bpp;
if (doubleheight) vga.draw.lines_scaled=2;
else vga.draw.lines_scaled=1;
#if C_DEBUG
@ -1434,14 +1487,14 @@ void VGA_SetupDrawing(Bitu /*val*/) {
LOG(LOG_VGA,LOG_NORMAL)("%s width, %s height aspect %f",
doublewidth ? "double":"normal",doubleheight ? "double":"normal",aspect_ratio);
#endif
RENDER_SetSize(width,height,bpp,fps,aspect_ratio,doublewidth,doubleheight);
vga.draw.delay.framestart = PIC_FullIndex();
PIC_AddEvent( VGA_VerticalTimer , (float)vga.draw.delay.vtotal );
vga.draw.lines_done = 0;
RENDER_SetSize(width,height,bpp,(float)fps,aspect_ratio,doublewidth,doubleheight);
}
}
void VGA_KillDrawing(void) {
PIC_RemoveEvents(VGA_DrawPart);
PIC_RemoveEvents(VGA_DrawSingleLine);
vga.draw.parts_left = 0;
vga.draw.lines_done = ~0;
RENDER_EndUpdate(true);
}

View File

@ -49,8 +49,10 @@ static void write_crtc_data_other(Bitu /*port*/,Bitu val,Bitu /*iolen*/) {
case 0x02: //Horizontal sync position
vga.other.hsyncp=(Bit8u)val;
break;
case 0x03: //Horizontal and vertical sync width
vga.other.syncw=(Bit8u)val;
case 0x03: //Horizontal sync width
if (machine==MCH_TANDY) vga.other.vsyncw=(Bit8u)(val >> 4);
else vga.other.vsyncw = 16; // The MC6845 has a fixed v-sync width of 16 lines
vga.other.hsyncw=(Bit8u)(val & 0xf);
break;
case 0x04: //Vertical total
if (vga.other.vtotal ^ val) VGA_StartResize();
@ -116,7 +118,9 @@ static Bitu read_crtc_data_other(Bitu /*port*/,Bitu /*iolen*/) {
case 0x02: //Horizontal sync position
return vga.other.hsyncp;
case 0x03: //Horizontal and vertical sync width
return vga.other.syncw;
if (machine==MCH_TANDY)
return vga.other.hsyncw | (vga.other.vsyncw << 4);
else return vga.other.hsyncw;
case 0x04: //Vertical total
return vga.other.vtotal;
case 0x05: //Vertical display adjust
@ -152,6 +156,7 @@ static Bitu read_crtc_data_other(Bitu /*port*/,Bitu /*iolen*/) {
static double hue_offset = 0.0;
static Bit8u cga16_val = 0;
static void update_cga16_color(void);
static Bit8u herc_pal = 0;
static void cga16_color_select(Bit8u val) {
cga16_val = val;
@ -278,17 +283,21 @@ static void TANDY_FindMode(void) {
}
}
void VGA_SetModeNow(VGAModes mode);
static void PCJr_FindMode(void) {
if (vga.tandy.mode_control & 0x2) {
if (vga.tandy.mode_control & 0x10) {
/* bit4 of mode control 1 signals 16 colour graphics mode */
VGA_SetMode(M_TANDY16);
if (vga.mode==M_TANDY4) VGA_SetModeNow(M_TANDY16); // TODO lowres mode only
else VGA_SetMode(M_TANDY16);
} else if (vga.tandy.gfx_control & 0x08) {
/* bit3 of mode control 2 signals 2 colour graphics mode */
VGA_SetMode(M_TANDY2);
} else {
/* otherwise some 4-colour graphics mode */
VGA_SetMode(M_TANDY4);
if (vga.mode==M_TANDY16) VGA_SetModeNow(M_TANDY4);
else VGA_SetMode(M_TANDY4);
}
write_color_select(vga.tandy.color_select);
} else {
@ -318,6 +327,7 @@ static void write_tandy_reg(Bit8u val) {
vga.tandy.mode_control=val;
VGA_SetBlinking(val & 0x20);
PCJr_FindMode();
vga.attr.disabled = (val&0x8)? 0: 1;
} else {
LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index);
}
@ -359,6 +369,7 @@ static void write_cga(Bitu port,Bitu val,Bitu /*iolen*/) {
switch (port) {
case 0x3d8:
vga.tandy.mode_control=(Bit8u)val;
vga.attr.disabled = (val&0x8)? 0: 1;
if (vga.tandy.mode_control & 0x2) {
if (vga.tandy.mode_control & 0x10) {
if (!(val & 0x4) && machine==MCH_CGA) {
@ -446,6 +457,30 @@ static void write_pcjr(Bitu port,Bitu val,Bitu /*iolen*/) {
}
}
static void CycleHercPal(bool pressed) {
if (!pressed) return;
if (++herc_pal>2) herc_pal=0;
Herc_Palette();
VGA_DAC_CombineColor(1,7);
}
void Herc_Palette(void) {
switch (herc_pal) {
case 0: // White
VGA_DAC_SetEntry(0x7,0x2a,0x2a,0x2a);
VGA_DAC_SetEntry(0xf,0x3f,0x3f,0x3f);
break;
case 1: // Amber
VGA_DAC_SetEntry(0x7,0x34,0x20,0x00);
VGA_DAC_SetEntry(0xf,0x3f,0x34,0x00);
break;
case 2: // Green
VGA_DAC_SetEntry(0x7,0x00,0x26,0x00);
VGA_DAC_SetEntry(0xf,0x00,0x3f,0x00);
break;
}
}
static void write_hercules(Bitu port,Bitu val,Bitu /*iolen*/) {
switch (port) {
case 0x3b8: {
@ -522,7 +557,7 @@ Bitu read_herc_status(Bitu /*port*/,Bitu /*iolen*/) {
void VGA_SetupOther(void) {
Bitu i;
memset( &vga.tandy, 0, sizeof( vga.tandy ));
vga.attr.enabled = true;
vga.attr.disabled = 0;
vga.config.bytes_skip=0;
//Initialize values common for most machines, can be overwritten
@ -541,6 +576,7 @@ void VGA_SetupOther(void) {
extern Bit8u int10_font_14[256 * 14];
for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_14[i*14],14);
vga.draw.font_tables[0]=vga.draw.font_tables[1]=vga.draw.font;
MAPPER_AddHandler(CycleHercPal,MK_f11,0,"hercpal","Herc Pal");
}
if (machine==MCH_CGA) {
IO_RegisterWriteHandler(0x3d8,write_cga,IO_MB);

View File

@ -355,7 +355,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) {
switch (reg) {
case 0x24: /* attribute controller index (read only) */
case 0x26:
return (vga.attr.enabled?0x20:0x00) | (vga.attr.index&0x1f);
return ((vga.attr.disabled & 1)?0x00:0x20) | (vga.attr.index & 0x1f);
case 0x2d: /* Extended Chip ID (high byte of PCI device ID) */
return 0x88;
case 0x2e: /* New Chip ID (low byte of PCI device ID) */

View File

@ -47,6 +47,8 @@ void write_p3c5(Bitu /*port*/,Bitu val,Bitu iolen) {
} else {
seq(clocking_mode)=val;
}
if (val & 0x20) vga.attr.disabled |= 0x2;
else vga.attr.disabled &= ~0x2;
}
/* TODO Figure this out :)
0 If set character clocks are 8 dots wide, else 9.

View File

@ -826,13 +826,6 @@ void BIOS_ZeroExtendedSize(bool in) {
if(other_memsystems < 0) other_memsystems=0;
}
#define RAM_REFRESH_DELAY 16.7f
static void RAMRefresh_Event(Bitu /*val*/) {
PIC_ActivateIRQ(5);
PIC_AddEvent(RAMRefresh_Event,RAM_REFRESH_DELAY);
}
void BIOS_SetupKeyboard(void);
void BIOS_SetupDisks(void);
@ -1085,8 +1078,6 @@ public:
size_extended=IO_Read(0x71);
IO_Write(0x70,0x31);
size_extended|=(IO_Read(0x71) << 8);
if (machine==MCH_PCJR) PIC_AddEvent(RAMRefresh_Event,RAM_REFRESH_DELAY);
}
~BIOS(){
/* abort DAC playing */

View File

@ -124,8 +124,9 @@ bool getSwapRequest(void) {
void swapInNextDisk(bool pressed) {
if (!pressed)
return;
/* Hack/feature: rescan all disks as well */
DriveManager::CycleAllDisks();
/* Hack/feature: rescan all disks as well */
LOG_MSG("Diskcaching reset for normal mounted drives.");
for(Bitu i=0;i<DOS_DRIVES;i++) {
if (Drives[i]) Drives[i]->EmptyCache();
}

View File

@ -246,7 +246,7 @@ static Bitu IRQ1_Handler(void) {
flags2&=~(0x40+0x20);//remove numlock/capslock pressed (hack for sdl only reporting states)
#endif
if (DOS_LayoutKey(scancode,flags1,flags2,flags3)) return CBRET_NONE;
LOG_MSG("key input %d %d %d %d",scancode,flags1,flags2,flags3);
//LOG_MSG("key input %d %d %d %d",scancode,flags1,flags2,flags3);
switch (scancode) {
/* First the hard ones */
case 0xfa: /* ack. Do nothing for now */

View File

@ -419,18 +419,24 @@ graphics_chars:
LOG(LOG_INT10,LOG_ERROR)("Function 12:Call %2X not handled",reg_bl);
reg_al=0x12;
break;
case 0x36: /* VGA Refresh control */
case 0x36: { /* VGA Refresh control */
if (!IS_VGA_ARCH) break;
if ((svgaCard==SVGA_S3Trio) && (reg_al>1)) {
reg_al=0;
break;
}
/*
Call disables/enables the vga from outputting video,
don't support it, but fake a success return
*/
reg_al=0x12;
IO_Write(0x3c4,0x1);
Bit8u clocking = IO_Read(0x3c5);
if (reg_al==0) clocking &= ~0x20;
else clocking |= 0x20;
IO_Write(0x3c4,0x1);
IO_Write(0x3c5,clocking);
reg_al=0x12; // success
break;
}
default:
LOG(LOG_INT10,LOG_ERROR)("Function 12:Call %2X not handled",reg_bl);
if (machine!=MCH_EGA) reg_al=0;

View File

@ -236,6 +236,13 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit
EGA16_CopyRow(cul,clr,start,start+nlines,base);break;
case M_VGA:
VGA_CopyRow(cul,clr,start,start+nlines,base);break;
case M_LIN4:
if ((machine==MCH_VGA) && (svgaCard==SVGA_TsengET4K) &&
(CurMode->swidth<=800)) {
// the ET4000 BIOS supports text output in 800x600 SVGA
EGA16_CopyRow(cul,clr,start,start+nlines,base);break;
}
// fall-through
default:
LOG(LOG_INT10,LOG_ERROR)("Unhandled mode %d for scroll",CurMode->type);
}
@ -262,6 +269,12 @@ filling:
EGA16_FillRow(cul,clr,start,base,attr);break;
case M_VGA:
VGA_FillRow(cul,clr,start,base,attr);break;
case M_LIN4:
if ((machine==MCH_VGA) && (svgaCard==SVGA_TsengET4K) &&
(CurMode->swidth<=800)) {
EGA16_FillRow(cul,clr,start,base,attr);break;
}
// fall-through
default:
LOG(LOG_INT10,LOG_ERROR)("Unhandled mode %d for scroll",CurMode->type);
}

View File

@ -475,7 +475,7 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) {
//Vertical displayed
IO_WriteW(crtc_base,0x06 | (CurMode->vdispend) << 8);
//Vertical sync position
IO_WriteW(crtc_base,0x07 | (CurMode->vdispend+1) << 8);
IO_WriteW(crtc_base,0x07 | (CurMode->vdispend + ((CurMode->vtotal - CurMode->vdispend)/2)-1) << 8);
//Maximum scanline
Bit8u scanline,crtpage;
scanline=8;
@ -504,7 +504,7 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) {
//Setup the special registers for each machine type
Bit8u mode_control_list[0xa+1]={
0x2c,0x28,0x2d,0x29, //0-3
0x2a,0x2e,0x16,0x29, //4-7
0x2a,0x2e,0x1e,0x29, //4-7
0x2a,0x2b,0x3b //8-a
};
Bit8u mode_control_list_pcjr[0xa+1]={
@ -517,6 +517,7 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) {
case MCH_HERC:
IO_WriteB(0x3b8,0x28); // TEXT mode and blinking characters
Herc_Palette();
VGA_DAC_CombineColor(0,0);
VGA_DAC_CombineColor(1,7);

View File

@ -94,6 +94,13 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) {
real_writeb(0xb800,off,old);
}
break;
case M_LIN4:
if ((machine!=MCH_VGA) || (svgaCard!=SVGA_TsengET4K) ||
(CurMode->swidth>800)) {
// the ET4000 BIOS supports text output in 800x600 SVGA (Gateway 2)
// putpixel warining?
break;
}
case M_EGA:
{
/* Set the correct bitmask for the pixel position */

View File

@ -1704,4 +1704,4 @@ int main(int argc, char *argv[])
}
#endif
#endif
#endif

View File

@ -213,7 +213,7 @@ bool Property::CheckValue(Value const& in, bool warn){
return true;
}
}
if(warn) LOG_MSG("\"%s\" is not a valid value for variable: %s.\nIt might now be reset it to default value: %s",in.ToString().c_str(),propname.c_str(),default_value.ToString().c_str());
if(warn) LOG_MSG("\"%s\" is not a valid value for variable: %s.\nIt might now be reset to the default value: %s",in.ToString().c_str(),propname.c_str(),default_value.ToString().c_str());
return false;
}

View File

@ -1,4 +1,4 @@
#define VERSION "0.73"
#define VERSION "0.74"
/* Define to 1 to enable internal debugger, requires libcurses */
#define C_DEBUG 0

View File

@ -38,6 +38,13 @@ void InitFreeType(uint8_t* fontBuffer, FT_Long bufferSize)
fontSystem[i] = NULL;
}
void DeinitFreeType()
{
ClearFontData();
FT_Done_FreeType(ftLibrary);
ftLibrary = NULL;
}
void ChangeFontSize(FT_UInt pixelSize)
{
FT_Set_Pixel_Sizes(ftFace, 0, pixelSize);
@ -65,25 +72,70 @@ void ClearFontData()
wchar_t* charToWideChar(const char* strChar)
{
wchar_t *strWChar;
strWChar = new wchar_t[strlen(strChar) + 1];
wchar_t *strWChar = new(std::nothrow) wchar_t[strlen(strChar) + 1];
if(!strWChar)
return NULL;
char *tempSrc = (char *)strChar;
int bt = mbstowcs(strWChar, strChar, strlen(strChar));
if (bt > 0)
{
strWChar[bt] = (wchar_t)'\0';
return strWChar;
}
wchar_t *tempDest = strWChar;
while((*tempDest++ = *tempSrc++));
while ((*tempDest++ = *strChar++));
return strWChar;
}
static uint32_t* convertBufferToRGBA8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = (bufferWidth * bufferHeight) << 2;
uint32_t* dataBufferRGBA8 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferRGBA8, 0x00, bufferSize);
uint8_t *src = (uint8_t *)rgbaBuffer;
uint8_t *dst = (uint8_t *)dataBufferRGBA8;
for(uint32_t block = 0; block < bufferHeight; block += 4) {
for(uint32_t i = 0; i < bufferWidth; i += 4) {
for (uint32_t c = 0; c < 4; c++) {
uint32_t blockWid = (((block + c) * bufferWidth)+i)<<2 ;
*dst++ = src[blockWid+ 3]; // ar = 0
*dst++ = src[blockWid+ 0];
*dst++ = src[blockWid+ 7]; // ar = 1
*dst++ = src[blockWid+ 4];
*dst++ = src[blockWid+ 11]; // ar = 2
*dst++ = src[blockWid+ 8];
*dst++ = src[blockWid+ 15]; // ar = 3
*dst++ = src[blockWid+ 12];
}
for (uint32_t c = 0; c < 4; c++) {
uint32_t blockWid = (((block + c) * bufferWidth)+i)<<2 ;
*dst++ = src[blockWid+ 1]; // gb = 0
*dst++ = src[blockWid+ 2];
*dst++ = src[blockWid+ 5]; // gb = 1
*dst++ = src[blockWid+ 6];
*dst++ = src[blockWid+ 9]; // gb = 2
*dst++ = src[blockWid+ 10];
*dst++ = src[blockWid+ 13]; // gb = 3
*dst++ = src[blockWid+ 14];
}
}
}
DCFlushRange(dataBufferRGBA8, bufferSize);
return dataBufferRGBA8;
}
/**
* Default constructor for the FreeTypeGX class.
*
* @param textureFormat Optional format (GX_TF_*) of the texture as defined by the libogc gx.h header file. If not specified default value is GX_TF_RGBA8.
* @param vertexIndex Optional vertex format index (GX_VTXFMT*) of the glyph textures as defined by the libogc gx.h header file. If not specified default value is GX_VTXFMT1.
*/
FreeTypeGX::FreeTypeGX(FT_UInt pixelSize, uint8_t textureFormat, uint8_t vertexIndex)
FreeTypeGX::FreeTypeGX(FT_UInt pixelSize, uint8_t vertexIndex)
{
this->textureFormat = textureFormat;
this->setVertexFormat(vertexIndex);
this->setCompatibilityMode(FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_PASSCLR | FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_NONE);
this->ftPointSize = pixelSize;
@ -195,67 +247,15 @@ void FreeTypeGX::unloadFont()
this->fontData.clear();
}
/**
* Adjusts the texture data buffer to necessary width for a given texture format.
*
* This routine determines adjusts the given texture width into the required width to hold the necessary texture data for proper alignment.
*
* @param textureWidth The initial guess for the texture width.
* @param textureFormat The texture format to which the data is to be converted.
* @return The correctly adjusted texture width.
*/
uint16_t FreeTypeGX::adjustTextureWidth(uint16_t textureWidth, uint8_t textureFormat)
uint16_t FreeTypeGX::adjustTextureWidth(uint16_t textureWidth)
{
uint16_t alignment;
switch(textureFormat)
{
case GX_TF_I4: /* 8x8 Tiles - 4-bit Intensity */
case GX_TF_I8: /* 8x4 Tiles - 8-bit Intensity */
case GX_TF_IA4: /* 8x4 Tiles - 4-bit Intensity, , 4-bit Alpha */
alignment = 8;
break;
case GX_TF_IA8: /* 4x4 Tiles - 8-bit Intensity, 8-bit Alpha */
case GX_TF_RGB565: /* 4x4 Tiles - RGB565 Format */
case GX_TF_RGB5A3: /* 4x4 Tiles - RGB5A3 Format */
case GX_TF_RGBA8: /* 4x4 Tiles - RGBA8 Dual Cache Line Format */
default:
alignment = 4;
break;
}
uint16_t alignment = 4;
return textureWidth % alignment == 0 ? textureWidth : alignment + textureWidth - (textureWidth % alignment);
}
/**
* Adjusts the texture data buffer to necessary height for a given texture format.
*
* This routine determines adjusts the given texture height into the required height to hold the necessary texture data for proper alignment.
*
* @param textureHeight The initial guess for the texture height.
* @param textureFormat The texture format to which the data is to be converted.
* @return The correctly adjusted texture height.
*/
uint16_t FreeTypeGX::adjustTextureHeight(uint16_t textureHeight, uint8_t textureFormat)
uint16_t FreeTypeGX::adjustTextureHeight(uint16_t textureHeight)
{
uint16_t alignment;
switch(textureFormat)
{
case GX_TF_I4: /* 8x8 Tiles - 4-bit Intensity */
alignment = 8;
break;
case GX_TF_I8: /* 8x4 Tiles - 8-bit Intensity */
case GX_TF_IA4: /* 8x4 Tiles - 4-bit Intensity, , 4-bit Alpha */
case GX_TF_IA8: /* 4x4 Tiles - 8-bit Intensity, 8-bit Alpha */
case GX_TF_RGB565: /* 4x4 Tiles - RGB565 Format */
case GX_TF_RGB5A3: /* 4x4 Tiles - RGB5A3 Format */
case GX_TF_RGBA8: /* 4x4 Tiles - RGBA8 Dual Cache Line Format */
default:
alignment = 4;
break;
}
uint16_t alignment = 4;
return textureHeight % alignment == 0 ? textureHeight : alignment + textureHeight - (textureHeight % alignment);
}
@ -280,8 +280,8 @@ ftgxCharData *FreeTypeGX::cacheGlyphData(wchar_t charCode)
if(ftSlot->format == FT_GLYPH_FORMAT_BITMAP) {
FT_Bitmap *glyphBitmap = &ftSlot->bitmap;
textureWidth = adjustTextureWidth(glyphBitmap->width, this->textureFormat);
textureHeight = adjustTextureHeight(glyphBitmap->rows, this->textureFormat);
textureWidth = adjustTextureWidth(glyphBitmap->width);
textureHeight = adjustTextureHeight(glyphBitmap->rows);
this->fontData[charCode] = (ftgxCharData){
ftSlot->bitmap_left,
@ -346,32 +346,7 @@ void FreeTypeGX::loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData)
glyphData[imagePosY * charData->textureWidth + imagePosX] = 0x00000000 | (pixel << 24) | (pixel << 16) | (pixel << 8) | pixel;
}
}
switch(this->textureFormat)
{
case GX_TF_I4:
charData->glyphDataTexture = Metaphrasis::convertBufferToI4(glyphData, charData->textureWidth, charData->textureHeight);
break;
case GX_TF_I8:
charData->glyphDataTexture = Metaphrasis::convertBufferToI8(glyphData, charData->textureWidth, charData->textureHeight);
break;
case GX_TF_IA4:
charData->glyphDataTexture = Metaphrasis::convertBufferToIA4(glyphData, charData->textureWidth, charData->textureHeight);
break;
case GX_TF_IA8:
charData->glyphDataTexture = Metaphrasis::convertBufferToIA8(glyphData, charData->textureWidth, charData->textureHeight);
break;
case GX_TF_RGB565:
charData->glyphDataTexture = Metaphrasis::convertBufferToRGB565(glyphData, charData->textureWidth, charData->textureHeight);
break;
case GX_TF_RGB5A3:
charData->glyphDataTexture = Metaphrasis::convertBufferToRGB5A3(glyphData, charData->textureWidth, charData->textureHeight);
break;
case GX_TF_RGBA8:
default:
charData->glyphDataTexture = Metaphrasis::convertBufferToRGBA8(glyphData, charData->textureWidth, charData->textureHeight);
break;
}
charData->glyphDataTexture = convertBufferToRGBA8(glyphData, charData->textureWidth, charData->textureHeight);
free(glyphData);
}
@ -485,7 +460,7 @@ uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color
x_pos += pairDelta.x >> 6;
}
GX_InitTexObj(&glyphTexture, glyphData->glyphDataTexture, glyphData->textureWidth, glyphData->textureHeight, this->textureFormat, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObj(&glyphTexture, glyphData->glyphDataTexture, glyphData->textureWidth, glyphData->textureHeight, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
this->copyTextureToFramebuffer(&glyphTexture, glyphData->textureWidth, glyphData->textureHeight, x_pos + glyphData->renderOffsetX + x_offset, y - glyphData->renderOffsetY + y_offset, color);
x_pos += glyphData->glyphAdvanceX;
@ -538,10 +513,10 @@ uint16_t FreeTypeGX::getWidth(wchar_t *text)
std::map<wchar_t, ftgxCharData>::iterator thisEnd =this->fontData.end();
for (uint32_t i = 0; i < strLength; ++i){
for (uint32_t i = 0; i < strLength; ++i)
{
ftgxCharData* glyphData = NULL;
if( this->fontData.find(text[i]) != thisEnd)
if(this->fontData.find(text[i]) != thisEnd)
{
glyphData = &this->fontData[text[i]];
}
@ -554,7 +529,7 @@ uint16_t FreeTypeGX::getWidth(wchar_t *text)
{
if(this->ftKerningEnabled && (i > 0))
{
FT_Get_Kerning( ftFace, this->fontData[text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta );
FT_Get_Kerning(ftFace, this->fontData[text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta);
strWidth += pairDelta.x >> 6;
}
strWidth += glyphData->glyphAdvanceX;

View File

@ -2,7 +2,7 @@
* FreeTypeGX is a wrapper class for libFreeType which renders a compiled
* FreeType parsable font into a GX texture for Wii homebrew development.
* Copyright (C) 2008 Armin Tamzarian
* Modified by Tantric, 2009
* Modified by Tantric, 2009-2010
*
* This file is part of FreeTypeGX.
*
@ -20,134 +20,6 @@
* along with FreeTypeGX. If not, see <http://www.gnu.org/licenses/>.
*/
/** \mainpage FreeTypeGX
*
* \section sec_intro Introduction
*
* FreeTypeGX is a wrapper class for libFreeType which renders a compiled FreeType parsable font into a GX texture for Wii homebrew development.
* <br>
* FreeTypeGX is written in C++ and makes use of a selectable pre-buffered or buffer-on-demand methodology to allow fast and efficient printing of text to the EFB.
* <p>
* This library was developed in-full by Armin Tamzarian with the support of developers in \#wiibrew on EFnet.
*
* \section sec_installation_source Installation (Source Code)
*
* -# Ensure that you have the <a href = "http://www.tehskeen.com/forums/showthread.php?t=9404">libFreeType</a> Wii library installed in your development environment with the library added to your Makefile where appropriate.
* -# Ensure that you have the <a href = "http://code.google.com/p/metaphrasis">Metaphrasis</a> library installed in your development environment with the library added to your Makefile where appropriate.
* -# Extract the FreeTypeGX archive.
* -# Copy the contents of the <i>src</i> directory into your project's development path.
* -# Include the FreeTypeGX header file in your code using syntax such as the following:
* \code
* #include "FreeTypeGX.h"
* \endcode
*
* \section sec_installation_library Installation (Library)
*
* -# Ensure that you have the <a href = "http://www.tehskeen.com/forums/showthread.php?t=9404">libFreeType</a> Wii library installed in your development environment with the library added to your Makefile where appropriate.
* -# Ensure that you have the <a href = "http://code.google.com/p/metaphrasis">Metaphrasis</a> library installed in your development environment with the library added to your Makefile where appropriate.
* -# Extract the FreeTypeGX archive.
* -# Copy the contents of the <i>lib</i> directory into your <i>devKitPro/libogc</i> directory.
* -# Include the FreeTypeGX header file in your code using syntax such as the following:
* \code
* #include "FreeTypeGX.h"
* \endcode
*
* \section sec_freetypegx_prerequisites FreeTypeGX Prerequisites
*
* Before you begin using FreeTypeGX in your project you must ensure that the desired font in compiled into your project. For this example I will assume you are building your project with a Makefile using devKitPro evironment and are attempting to include a font whose filename is rursus_compact_mono.ttf.
*
* -# Copy the font into a directory which will be processed by the project's Makefile. If you are unsure about where you should place your font just copy the it into your project's source directory.
* \n\n
* -# Modify the Makefile to convert the font into an object file:
* \code
* %.ttf.o : %.ttf
* @echo $(notdir $<)
* $(bin2o)
* \endcode
* \n
* -# Include the font object's generated header file in your source code:
* \code
* #include "rursus_compact_mono_ttf.h"
* \endcode
* This header file defines the two variables that you will need for use within your project:
* \code
* extern const u8 rursus_compact_mono_ttf[]; A pointer to the font buffer within the compiled project.
* extern const u32 rursus_compact_mono_ttf_size; The size of the font's buffer in bytes.
* \endcode
*
* \section sec_freetypegx_usage FreeTypeGX Usage
*
* -# Within the file you included the FreeTypeGX.h header create an instance object of the FreeTypeGX class:
* \code
* FreeTypeGX *freeTypeGX = new FreeTypeGX();
* \endcode
* Alternately you can specify a texture format to which you would like to render the font characters. Note that the default value for this parameter is GX_TF_RGBA8.
* \code
* FreeTypeGX *freeTypeGX = new FreeTypeGX(GX_TF_RGB565);
* \endcode
* Furthermore, you can also specify a vertex format index to avoid conflicts with concurrent libraries or other systems. Note that the default value for this parameter is GX_VTXFMT1.
* \code
* FreeTypeGX *freeTypeGX = new FreeTypeGX(GX_TF_RGB565, GX_VTXFMT1);
* \endcode
* \n
* Currently supported textures are:
* \li <i>GX_TF_I4</i>
* \li <i>GX_TF_I8</i>
* \li <i>GX_TF_IA4</i>
* \li <i>GX_TF_IA8</i>
* \li <i>GX_TF_RGB565</i>
* \li <i>GX_TF_RGB5A3</i>
* \li <i>GX_TF_RGBA8</i>
*
* \n
* -# Using the allocated FreeTypeGX instance object call the loadFont function to load the font from the compiled buffer and specify the desired point size. Note that this function can be called multiple times to load a new:
* \code
* freeTypeGX->loadFont(rursus_compact_mono_ttf, rursus_compact_mono_ttf_size, 64);
* \endcode
* Alternately you can specify a flag which will load and cache all available font glyphs immidiately. Note that on large font sets enabling this feature could take a significant amount of time.
* \code
* freeTypeGX->loadFont(rursus_compact_mono_ttf, rursus_compact_mono_ttf_size, 64, true);
* \endcode
* \n
* -# If necessary you can enable compatibility modes with concurrent libraries or systems. For more information on this feature see the documentation for setCompatibilityMode:
* \code
* freeTypeGX->setCompatibilityMode(FTGX_COMPATIBILITY_GRRLIB);
* \endcode
* -# Using the allocated FreeTypeGX instance object call the drawText function to print a string at the specified screen X and Y coordinates to the current EFB:
* \code
* freeTypeGX->drawText(10, 25, _TEXT("FreeTypeGX Rocks!"));
* \endcode
* Alternately you can specify a <i>GXColor</i> object you would like to apply to the printed characters:
* \code
* freeTypeGX->drawText(10, 25, _TEXT("FreeTypeGX Rocks!"),
* (GXColor){0xff, 0xee, 0xaa, 0xff});
* \endcode
* Furthermore you can also specify a group of styling parameters which will modify the positioning or style of the text:
* \code
* freeTypeGX->drawText(10, 25, _TEXT("FreeTypeGX Rocks!"),
* (GXColor){0xff, 0xee, 0xaa, 0xff},
* FTGX_JUSTIFY_CENTER | FTGX_ALIGN_BOTTOM | FTGX_STYLE_UNDERLINE);
* \endcode
* \n
* Currently style parameters are:
* \li <i>FTGX_JUSTIFY_LEFT</i>
* \li <i>FTGX_JUSTIFY_CENTER</i>
* \li <i>FTGX_JUSTIFY_RIGHT</i>
* \li <i>FTGX_ALIGN_TOP</i>
* \li <i>FTGX_ALIGN_MIDDLE</i>
* \li <i>FTGX_ALIGN_BOTTOM</i>
* \li <i>FTGX_STYLE_UNDERLINE</i>
* \li <i>FTGX_STYLE_STRIKE</i>
*
* \section sec_license License
*
* FreeTypeGX is distributed under the GNU Lesser General Public License.
*
* \section sec_contact Contact
*
* If you have any suggestions, questions, or comments regarding this library feel free to e-mail me at tamzarian1989 [at] gmail [dawt] com.
*/
#ifndef FREETYPEGX_H_
#define FREETYPEGX_H_
@ -155,7 +27,6 @@
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_BITMAP_H
#include "Metaphrasis.h"
#include <malloc.h>
#include <string.h>
@ -236,6 +107,7 @@ typedef struct ftgxDataOffset_ ftgxDataOffset;
const GXColor ftgxWhite = (GXColor){0xff, 0xff, 0xff, 0xff}; /**< Constant color value used only to sanitize Doxygen documentation. */
void InitFreeType(uint8_t* fontBuffer, FT_Long bufferSize);
void DeinitFreeType();
void ChangeFontSize(FT_UInt pixelSize);
wchar_t* charToWideChar(const char* p);
void ClearFontData();
@ -254,14 +126,12 @@ class FreeTypeGX {
private:
FT_UInt ftPointSize; /**< Requested size of the rendered font. */
bool ftKerningEnabled; /**< Flag indicating the availability of font kerning data. */
uint8_t textureFormat; /**< Defined texture format of the target EFB. */
uint8_t vertexIndex; /**< Vertex format descriptor index. */
uint32_t compatibilityMode; /**< Compatibility mode for default tev operations and vertex descriptors. */
std::map<wchar_t, ftgxCharData> fontData; /**< Map which holds the glyph data structures for the corresponding characters. */
static uint16_t adjustTextureWidth(uint16_t textureWidth, uint8_t textureFormat);
static uint16_t adjustTextureHeight(uint16_t textureHeight, uint8_t textureFormat);
static uint16_t adjustTextureWidth(uint16_t textureWidth);
static uint16_t adjustTextureHeight(uint16_t textureHeight);
static int16_t getStyleOffsetWidth(uint16_t width, uint16_t format);
static int16_t getStyleOffsetHeight(ftgxDataOffset *offset, uint16_t format);
@ -278,7 +148,7 @@ class FreeTypeGX {
void copyFeatureToFramebuffer(f32 featureWidth, f32 featureHeight, int16_t screenX, int16_t screenY, GXColor color);
public:
FreeTypeGX(FT_UInt pixelSize, uint8_t textureFormat = GX_TF_RGBA8, uint8_t vertexIndex = GX_VTXFMT1);
FreeTypeGX(FT_UInt pixelSize, uint8_t vertexIndex = GX_VTXFMT1);
~FreeTypeGX();
void setVertexFormat(uint8_t vertexIndex);

View File

@ -1,392 +0,0 @@
/*
* Metaphrasis is a static conversion class for transforming RGBA image
* buffers into verious GX texture formats for Wii homebrew development.
* Copyright (C) 2008 Armin Tamzarian
*
* This file is part of Metaphrasis.
*
* Metaphrasis is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Metaphrasis is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Metaphrasis. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Metaphrasis.h"
/**
* Default constructor for the Metaphrasis class.
*/
Metaphrasis::Metaphrasis() {
}
/**
* Default destructor for the Metaphrasis class.
*/
Metaphrasis::~Metaphrasis() {
}
/**
* Convert the specified RGBA data buffer into the I4 texture format
*
* This routine converts the RGBA data buffer into the I4 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToI4(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = bufferWidth * bufferHeight >> 1;
uint32_t* dataBufferI4 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferI4, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint8_t *dst = (uint8_t *)dataBufferI4;
for(uint32_t y = 0; y < bufferHeight; y += 8) {
for(uint32_t x = 0; x < bufferWidth; x += 8) {
for(uint32_t rows = 0; rows < 8; rows++) {
*dst++ = (src[((y + rows) * bufferWidth) + (x + 0)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 1)] & 0xf0) >> 4);
*dst++ = (src[((y + rows) * bufferWidth) + (x + 2)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 3)] & 0xf0) >> 4);
*dst++ = (src[((y + rows) * bufferWidth) + (x + 4)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 5)] & 0xf0) >> 4);
*dst++ = (src[((y + rows) * bufferWidth) + (x + 5)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 7)] & 0xf0) >> 4);
}
}
}
DCFlushRange(dataBufferI4, bufferSize);
return dataBufferI4;
}
/**
* Convert the specified RGBA data buffer into the I8 texture format
*
* This routine converts the RGBA data buffer into the I8 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToI8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = bufferWidth * bufferHeight;
uint32_t* dataBufferI8 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferI8, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint8_t *dst = (uint8_t *)dataBufferI8;
for(uint32_t rows = 0; rows < 4; rows++) {
for(uint32_t y = 0; y < bufferHeight; y += 4) {
uint32_t bufWid = ((y + rows) * bufferWidth);
for(uint32_t x = 0; x < bufferWidth; x += 8) {
*dst++ = src[bufWid + (x + 0)] & 0xff;
*dst++ = src[bufWid + (x + 1)] & 0xff;
*dst++ = src[bufWid + (x + 2)] & 0xff;
*dst++ = src[bufWid + (x + 3)] & 0xff;
*dst++ = src[bufWid + (x + 4)] & 0xff;
*dst++ = src[bufWid + (x + 5)] & 0xff;
*dst++ = src[bufWid + (x + 6)] & 0xff;
*dst++ = src[bufWid + (x + 7)] & 0xff;
}
}
}
DCFlushRange(dataBufferI8, bufferSize);
return dataBufferI8;
}
/**
* Downsample the specified RGBA value data buffer to an IA4 value.
*
* This routine downsamples the given RGBA data value into the IA4 texture data format.
*
* @param rgba A 32-bit RGBA value to convert to the IA4 format.
* @return The IA4 value of the given RGBA value.
*/
uint8_t Metaphrasis::convertRGBAToIA4(uint32_t rgba) {
uint8_t i = (rgba >> 8) & 0xf0;
uint8_t a = (rgba ) & 0xff;
return i | (a >> 4);
}
/**
* Convert the specified RGBA data buffer into the IA4 texture format
*
* This routine converts the RGBA data buffer into the IA4 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToIA4(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = bufferWidth * bufferHeight;
uint32_t* dataBufferIA4 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferIA4, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint8_t *dst = (uint8_t *)dataBufferIA4;
for(uint32_t y = 0; y < bufferHeight; y += 4) {
for(uint32_t x = 0; x < bufferWidth; x += 8) {
for(uint32_t rows = 0; rows < 4; rows++) {
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 0)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 1)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 2)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 3)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 4)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 5)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 6)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 7)]);
}
}
}
DCFlushRange(dataBufferIA4, bufferSize);
return dataBufferIA4;
}
/**
* Downsample the specified RGBA value data buffer to an IA8 value.
*
* This routine downsamples the given RGBA data value into the IA8 texture data format.
*
* @param rgba A 32-bit RGBA value to convert to the IA8 format.
* @return The IA8 value of the given RGBA value.
*/
uint16_t Metaphrasis::convertRGBAToIA8(uint32_t rgba) {
return (((rgba >> 8) & 0xff) << 8) | ((rgba ) & 0xff);
}
/**
* Convert the specified RGBA data buffer into the IA8 texture format
*
* This routine converts the RGBA data buffer into the IA8 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToIA8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = (bufferWidth * bufferHeight) << 1;
uint32_t* dataBufferIA8 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferIA8, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint16_t *dst = (uint16_t *)dataBufferIA8;
for(uint32_t rows = 0; rows < 4; ++rows) {
for(uint32_t y = 0; y < bufferHeight; y += 4) {
uint32_t bufWid = ((y + rows) * bufferWidth);
for(uint32_t x = 0; x < bufferWidth; x += 4) {
*dst++ = Metaphrasis::convertRGBAToIA8(src[bufWid + (x + 0)]);
*dst++ = Metaphrasis::convertRGBAToIA8(src[bufWid + (x + 1)]);
*dst++ = Metaphrasis::convertRGBAToIA8(src[bufWid + (x + 2)]);
*dst++ = Metaphrasis::convertRGBAToIA8(src[bufWid + (x + 3)]);
}
}
}
DCFlushRange(dataBufferIA8, bufferSize);
return dataBufferIA8;
}
/**
* Convert the specified RGBA data buffer into the RGBA8 texture format
*
* This routine converts the RGBA data buffer into the RGBA8 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToRGBA8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = (bufferWidth * bufferHeight) << 2;
uint32_t* dataBufferRGBA8 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferRGBA8, 0x00, bufferSize);
uint8_t *src = (uint8_t *)rgbaBuffer;
uint8_t *dst = (uint8_t *)dataBufferRGBA8;
for(uint32_t block = 0; block < bufferHeight; block += 4) {
for(uint32_t i = 0; i < bufferWidth; i += 4) {
for (uint32_t c = 0; c < 4; c++) {
uint32_t blockWid = (((block + c) * bufferWidth)+i)<<2 ;
*dst++ = src[blockWid+ 3]; // ar = 0
*dst++ = src[blockWid+ 0];
*dst++ = src[blockWid+ 7]; // ar = 1
*dst++ = src[blockWid+ 4];
*dst++ = src[blockWid+ 11]; // ar = 2
*dst++ = src[blockWid+ 8];
*dst++ = src[blockWid+ 15]; // ar = 3
*dst++ = src[blockWid+ 12];
}
for (uint32_t c = 0; c < 4; c++) {
uint32_t blockWid = (((block + c) * bufferWidth)+i)<<2 ;
*dst++ = src[blockWid+ 1]; // gb = 0
*dst++ = src[blockWid+ 2];
*dst++ = src[blockWid+ 5]; // gb = 1
*dst++ = src[blockWid+ 6];
*dst++ = src[blockWid+ 9]; // gb = 2
*dst++ = src[blockWid+ 10];
*dst++ = src[blockWid+ 13]; // gb = 3
*dst++ = src[blockWid+ 14];
}
}
}
DCFlushRange(dataBufferRGBA8, bufferSize);
return dataBufferRGBA8;
}
/**
* Downsample the specified RGBA value data buffer to an RGB565 value.
*
* This routine downsamples the given RGBA data value into the RGB565 texture data format.
* Attribution for this routine is given fully to NoNameNo of GRRLIB Wii library.
*
* @param rgba A 32-bit RGBA value to convert to the RGB565 format.
* @return The RGB565 value of the given RGBA value.
*/
uint16_t Metaphrasis::convertRGBAToRGB565(uint32_t rgba) {
uint32_t rA = ((rgba >> 24) & 0xff);
uint32_t gA = ((rgba >> 16) & 0xff);
uint32_t bA = ((rgba >> 8) & 0xff);
uint32_t r = ((rA<<5) - rA) / 255;
uint32_t g = ((gA<<6) - gA) / 255;
uint32_t b = ((bA<<5) - bA) / 255;
return (((r << 6) | g ) << 5 ) | b;
}
/**
* Convert the specified RGBA data buffer into the RGB565 texture format
*
* This routine converts the RGBA data buffer into the RGB565 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToRGB565(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = (bufferWidth * bufferHeight) << 1;
uint32_t* dataBufferRGB565 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferRGB565, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint16_t *dst = (uint16_t *)dataBufferRGB565;
for(uint32_t rows = 0; rows < 4; rows++) {
for(uint32_t y = 0; y < bufferHeight; y += 4) {
uint32_t bufWid = ((y + rows) * bufferWidth);
for(uint32_t x = 0; x < bufferWidth; x += 4) {
*dst++ = Metaphrasis::convertRGBAToRGB565(src[bufWid + (x + 0)]);
*dst++ = Metaphrasis::convertRGBAToRGB565(src[bufWid + (x + 1)]);
*dst++ = Metaphrasis::convertRGBAToRGB565(src[bufWid + (x + 2)]);
*dst++ = Metaphrasis::convertRGBAToRGB565(src[bufWid + (x + 3)]);
}
}
}
DCFlushRange(dataBufferRGB565, bufferSize);
return dataBufferRGB565;
}
/**
* Downsample the specified RGBA value data buffer to an RGB5A3 value.
*
* This routine downsamples the given RGBA data value into the RGB5A3 texture data format.
* Attribution for this routine is given fully to WiiGator via the TehSkeen forum.
*
* @param rgba A 32-bit RGBA value to convert to the RGB5A3 format.
* @return The RGB5A3 value of the given RGBA value.
*/
uint16_t Metaphrasis::convertRGBAToRGB5A3(uint32_t rgba) {
uint32_t r = (rgba >> 24) & 0xff;
uint32_t g = (rgba >> 16) & 0xff;
uint32_t b = (rgba >> 8) & 0xff;
uint32_t a = (rgba ) & 0xff;
uint16_t color;
// No predictive misses, faster shifting
if (a > 0xe0) {
r >>= 3;
g >>= 3;
b >>= 3;
color = (r << 10) | (g << 5) | b;
color |= 0x8000;
return color;
}
r >>= 4;
g >>= 4;
b >>= 4;
a >>= 5;
color = (a << 12) | (r << 8) | (g << 4) | b;
return color;
}
/**
* Convert the specified RGBA data buffer into the RGB5A3 texture format
*
* This routine converts the RGBA data buffer into the RGB5A3 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToRGB5A3(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = (bufferWidth * bufferHeight) << 1;
uint32_t* dataBufferRGB5A3 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferRGB5A3, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint16_t *dst = (uint16_t *)dataBufferRGB5A3;
for(uint32_t rows = 0; rows < 4; rows++) {
for(uint32_t y = 0; y < bufferHeight; y += 4) {
uint32_t bufWid = ((y + rows) * bufferWidth);
for(uint32_t x = 0; x < bufferWidth; x += 4) {
*dst++ = Metaphrasis::convertRGBAToRGB5A3(src[bufWid + (x + 0)]);
*dst++ = Metaphrasis::convertRGBAToRGB5A3(src[bufWid + (x + 1)]);
*dst++ = Metaphrasis::convertRGBAToRGB5A3(src[bufWid + (x + 2)]);
*dst++ = Metaphrasis::convertRGBAToRGB5A3(src[bufWid + (x + 3)]);
}
}
}
DCFlushRange(dataBufferRGB5A3, bufferSize);
return dataBufferRGB5A3;
}

View File

@ -1,116 +0,0 @@
/*
* Metaphrasis is a static conversion class for transforming RGBA image
* buffers into verious GX texture formats for Wii homebrew development.
* Copyright (C) 2008 Armin Tamzarian
*
* This file is part of Metaphrasis.
*
* Metaphrasis is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Metaphrasis is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Metaphrasis. If not, see <http://www.gnu.org/licenses/>.
*/
/** \mainpage Metaphrasis
*
* \section sec_intro Introduction
*
* Metaphrasis is a static conversion class for transforming RGBA image buffers into verious GX texture formats for Wii homebrew development.
* <br>
* Metaphrasis is written in C++ and makes use of a community standard and newly developed algorithms for conversion of 32-bit RGBA data buffers into various GX texture formats common to both the Gamecube and Wii platforms.
* <p>
* This library was developed in-full by Armin Tamzarian with the support of developers in \#wiibrew on EFnet, Chaosteil of libwiisprite, and DrTwox of GRRLIB.
*
* \section sec_installation_source Installation (Source Code)
*
* -# Extract the Metaphrasis archive.
* -# Copy the contents of the <i>src</i> directory into your project's development path.
* -# Include the Metaphrasis header file in your code using syntax such as the following:
* \code
* #include "Metaphrasis.h"
* \endcode
*
* \section sec_installation_library Installation (Library)
*
* -# Extract the Metaphrasis archive.
* -# Copy the contents of the <i>lib</i> directory into your <i>devKitPro/libogc</i> directory.
* -# Include the Metaphrasis header file in your code using syntax such as the following:
* \code
* #include "Metaphrasis.h"
* \endcode
*
* \section sec_usage Usage
*
* -# Create a buffer full of 32-bit RGBA values noting both the pixel height and width of the buffer.
* -# Call one of the many conversion routines from within your code. (Note: All methods within the Metaphrasis class are static and thus no class instance need be allocated)
* \code
* uint32_t* rgba8Buffer = Metaphrasis::convertBufferToRGBA8(rgbaBuffer, bufferWidth, bufferHeight);
* \endcode
* -# Free your temporary RGBA value buffer if you no longer need said values.
*
* Currently supported conversion routines are as follows:
* \li convertBufferToI4
* \li convertBufferToI8
* \li convertBufferToIA4
* \li convertBufferToIA8
* \li convertBufferToRGBA8
* \li convertBufferToRGB565
* \li convertBufferToRGB5A3
*
* \section sec_license License
*
* Metaphrasis is distributed under the GNU Lesser General Public License.
*
* \section sec_contact Contact
*
* If you have any suggestions, questions, or comments regarding this library feel free to e-mail me at tamzarian1989 [at] gmail [dawt] com.
*/
#ifndef METAPHRASIS_H_
#define METAPHRASIS_H_
#include <gccore.h>
#include <stdint.h>
#include <malloc.h>
#include <string.h>
/*! \class Metaphrasis
* \brief A static conversion class for transforming RGBA image buffers into verious GX texture formats for
* Wii homebrew development.
* \author Armin Tamzarian
* \version 0.1.0
*
* Metaphrasis is a static conversion class for transforming RGBA image buffers into verious GX texture formats for
* Wii homebrew development. Metaphrasis is written in C++ and makes use of a community standard and newly developed
* algorithms for conversion of 32-bit RGBA data buffers into various GX texture formats common to both the Gamecube
* and Wii platforms.
*/
class Metaphrasis {
public:
Metaphrasis();
virtual ~Metaphrasis();
static uint32_t* convertBufferToI4(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToI8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToIA4(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToIA8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToRGBA8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToRGB565(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToRGB5A3(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint8_t convertRGBAToIA4(uint32_t rgba);
static uint16_t convertRGBAToIA8(uint32_t rgba);
static uint16_t convertRGBAToRGB565(uint32_t rgba);
static uint16_t convertRGBAToRGB5A3(uint32_t rgba);
};
#endif /*METAPHRASIS_H_*/

View File

@ -1,4 +1,4 @@
#define VERSION "0.73"
#define VERSION "0.74"
/* Define to 1 to enable internal debugger, requires libcurses */
#define C_DEBUG 0

View File

@ -1,6 +1,6 @@
/****************************************************************************
* DOSBox Wii Home Menu
* Tantric 2009
* Tantric 2009-2010
*
* filelist.h
*

View File

@ -1,6 +1,6 @@
/****************************************************************************
* DOSBox Wii Home Menu
* Tantric 2009
* Tantric 2009-2010
*
* input.cpp
*

View File

@ -1,6 +1,6 @@
/****************************************************************************
* DOSBox Wii Home Menu
* Tantric 2009
* Tantric 2009-2010
*
* input.h
*

View File

@ -51,8 +51,9 @@
extern FreeTypeGX *fontSystem[];
#define SCROLL_INITIAL_DELAY 20
#define SCROLL_LOOP_DELAY 3
#define SCROLL_DELAY_INITIAL 200000
#define SCROLL_DELAY_LOOP 30000
#define SCROLL_DELAY_DECREASE 300
#define MAX_KEYBOARD_DISPLAY 32
typedef void (*UpdateCallback)(void * e);
@ -190,11 +191,19 @@ class GuiTrigger
//!\param wiibtns Wii controller trigger button(s) - classic controller buttons are considered separately
//!\param gcbtns GameCube controller trigger button(s)
void SetButtonOnlyInFocusTrigger(s32 ch, u32 wiibtns, u16 gcbtns);
//!Get X/Y value from Wii Joystick (classic, nunchuk) input
//!\param right Controller stick (left = 0, right = 1)
//!Get X or Y value from Wii Joystick (classic, nunchuk) input
//!\param stick Controller stick (left = 0, right = 1)
//!\param axis Controller stick axis (x-axis = 0, y-axis = 1)
//!\return Stick value
s8 WPAD_Stick(u8 right, int axis);
s8 WPAD_Stick(u8 stick, int axis);
//!Get X value from Wii Joystick (classic, nunchuk) input
//!\param stick Controller stick (left = 0, right = 1)
//!\return Stick value
s8 WPAD_StickX(u8 stick);
//!Get Y value from Wii Joystick (classic, nunchuk) input
//!\param stick Controller stick (left = 0, right = 1)
//!\return Stick value
s8 WPAD_StickY(u8 stick);
//!Move menu selection left (via pad/joystick). Allows scroll delay and button overriding
//!\return true if selection should be moved left, false otherwise
bool Left();
@ -208,11 +217,11 @@ class GuiTrigger
//!\return true if selection should be moved down, false otherwise
bool Down();
u8 type; //!< trigger type (TRIGGER_SIMPLE, TRIGGER_HELD, TRIGGER_BUTTON_ONLY, TRIGGER_BUTTON_ONLY_IN_FOCUS)
s32 chan; //!< Trigger controller channel (0-3, -1 for all)
WPADData * wpad; //!< Wii controller trigger
WPADData wpaddata; //!< Wii controller trigger data
PADData pad; //!< GameCube controller trigger data
WPADData * wpad; //!< Wii controller trigger
s32 chan; //!< Trigger controller channel (0-3, -1 for all)
u8 type; //!< trigger type (TRIGGER_SIMPLE, TRIGGER_HELD, TRIGGER_BUTTON_ONLY, TRIGGER_BUTTON_ONLY_IN_FOCUS)
};
extern GuiTrigger userInput[4];
@ -307,12 +316,28 @@ class GuiElement
//!Considers alpha, alphaDyn, and the parent element's GetAlpha() value
//!\return alpha
int GetAlpha();
//!Sets the element's scale
//!Sets the element's x and y scale
//!\param s scale (1 is 100%)
void SetScale(float s);
//!Sets the element's x scale
//!\param s scale (1 is 100%)
void SetScaleX(float s);
//!Sets the element's y scale
//!\param s scale (1 is 100%)
void SetScaleY(float s);
//!Sets the element's x and y scale, using the provided max width/height
//!\param w Maximum width
//!\param h Maximum height
void SetScale(int w, int h);
//!Gets the element's current scale
//!Considers scale, scaleDyn, and the parent element's GetScale() value
float GetScale();
//!Gets the element's current x scale
//!Considers scale, scaleDyn, and the parent element's GetScale() value
float GetScaleX();
//!Gets the element's current y scale
//!Considers scale, scaleDyn, and the parent element's GetScale() value
float GetScaleY();
//!Set a new GuiTrigger for the element
//!\param t Pointer to GuiTrigger
void SetTrigger(GuiTrigger * t);
@ -378,13 +403,19 @@ class GuiElement
//!\param hor Horizontal alignment (ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTRE)
//!\param vert Vertical alignment (ALIGN_TOP, ALIGN_BOTTOM, ALIGN_MIDDLE)
virtual void SetAlignment(int hor, int vert);
//!Called when the language has changed, to obtain new text values for all text elements
virtual void ResetText();
//!Called constantly to allow the element to respond to the current input data
//!\param t Pointer to a GuiTrigger, containing the current input data from PAD/WPAD
virtual void Update(GuiTrigger * t);
//!Called constantly to redraw the element
virtual void Draw();
//!Called constantly to redraw the element's tooltip
virtual void DrawTooltip();
protected:
bool visible; //!< Visibility of the element. If false, Draw() is skipped
GuiTrigger * trigger[3]; //!< GuiTriggers (input actions) that this element responds to
UpdateCallback updateCB; //!< Callback function to call when this element is updated
GuiElement * parentElement; //!< Parent element
int focus; //!< Element focus (-1 = focus disabled, 0 = not focused, 1 = focused)
int width; //!< Element width
int height; //!< Element height
@ -397,10 +428,10 @@ class GuiElement
int xoffsetDyn; //!< Element X offset, dynamic (added to xoffset value for animation effects)
int yoffsetDyn; //!< Element Y offset, dynamic (added to yoffset value for animation effects)
int alpha; //!< Element alpha value (0-255)
f32 scale; //!< Element scale (1 = 100%)
int alphaDyn; //!< Element alpha, dynamic (multiplied by alpha value for blending/fading effects)
f32 xscale; //!< Element X scale (1 = 100%)
f32 yscale; //!< Element Y scale (1 = 100%)
f32 scaleDyn; //!< Element scale, dynamic (multiplied by alpha value for blending/fading effects)
bool rumble; //!< Wiimote rumble (on/off) - set to on when this element requests a rumble event
int effects; //!< Currently enabled effect(s). 0 when no effects are enabled
int effectAmount; //!< Effect amount. Used by different effects for different purposes
int effectTarget; //!< Effect target amount. Used by different effects for different purposes
@ -414,9 +445,8 @@ class GuiElement
bool selectable; //!< Whether or not this element selectable (can change to SELECTED state)
bool clickable; //!< Whether or not this element is clickable (can change to CLICKED state)
bool holdable; //!< Whether or not this element is holdable (can change to HELD state)
GuiTrigger * trigger[2]; //!< GuiTriggers (input actions) that this element responds to
GuiElement * parentElement; //!< Parent element
UpdateCallback updateCB; //!< Callback function to call when this element is updated
bool visible; //!< Visibility of the element. If false, Draw() is skipped
bool rumble; //!< Wiimote rumble (on/off) - set to on when this element requests a rumble event
};
//!Allows GuiElements to be grouped together into a "window"
@ -443,6 +473,10 @@ class GuiWindow : public GuiElement
void Remove(GuiElement* e);
//!Removes all GuiElements
void RemoveAll();
//!Looks for the specified GuiElement
//!\param e The GuiElement to find
//!\return true if found, false otherwise
bool Find(GuiElement* e);
//!Returns the GuiElement at the specified index
//!\param index The index of the element
//!\return A pointer to the element at the index, NULL on error (eg: out of bounds)
@ -480,8 +514,12 @@ class GuiWindow : public GuiElement
//!Moves the selected element to the element above or below
//!\param d Direction to move (-1 = up, 1 = down)
void MoveSelectionVert(int d);
//!Resets the text for all contained elements
void ResetText();
//!Draws all the elements in this GuiWindow
void Draw();
//!Draws all of the tooltips in this GuiWindow
void DrawTooltip();
//!Updates the window and all elements contains within
//!Allows the GuiWindow and all elements to respond to the input data specified
//!\param t Pointer to a GuiTrigger, containing the current input data from PAD/WPAD
@ -497,7 +535,9 @@ class GuiImageData
//!Constructor
//!Converts the image data to RGBA8 - expects PNG format
//!\param i Image data
GuiImageData(const u8 * i);
//!\param w Max image width (0 = not set)
//!\param h Max image height (0 = not set)
GuiImageData(const u8 * i, int w=0, int h=0);
//!Destructor
~GuiImageData();
//!Gets a pointer to the image data
@ -600,6 +640,11 @@ class GuiText : public GuiElement
//!Sets the text of the GuiText element
//!\param t Text
void SetText(const char * t);
//!Sets the text of the GuiText element
//!\param t UTF-8 Text
void SetWText(wchar_t * t);
//!Gets the translated text length of the GuiText element
int GetLength();
//!Sets up preset values to be used by GuiText(t)
//!Useful when printing multiple text elements, all with the same attributes set
//!\param sz Font size
@ -615,6 +660,8 @@ class GuiText : public GuiElement
//!Sets the maximum width of the drawn texture image
//!\param w Maximum width
void SetMaxWidth(int w);
//!Gets the width of the text when rendered
int GetTextWidth();
//!Enables/disables text scrolling
//!\param s Scrolling on/off
void SetScroll(int s);
@ -632,21 +679,50 @@ class GuiText : public GuiElement
//!\param hor Horizontal alignment (ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTRE)
//!\param vert Vertical alignment (ALIGN_TOP, ALIGN_BOTTOM, ALIGN_MIDDLE)
void SetAlignment(int hor, int vert);
//!Updates the text to the selected language
void ResetText();
//!Constantly called to draw the text
void Draw();
protected:
char * origText; //!< Original text data
wchar_t* text; //!< Unicode text value
GXColor color; //!< Font color
wchar_t* text; //!< Translated Unicode text value
wchar_t *textDyn[20]; //!< Text value, if max width, scrolling, or wrapping enabled
int textDynNum; //!< Number of text lines
char * origText; //!< Original text data (English)
int size; //!< Font size
int maxWidth; //!< Maximum width of the generated text object (for text wrapping)
bool wrap; //!< Wrapping toggle
wchar_t* textDyn; //!< Wrapped text value
int textScroll; //!< Scrolling toggle
int textScrollPos; //!< Current starting index of text string for scrolling
int textScrollInitialDelay; //!< Delay to wait before starting to scroll
int textScrollDelay; //!< Scrolling speed
u16 style; //!< FreeTypeGX style attributes
GXColor color; //!< Font color
bool wrap; //!< Wrapping toggle
};
//!Display, manage, and manipulate tooltips in the GUI
class GuiTooltip : public GuiElement
{
public:
//!Constructor
//!\param t Text
GuiTooltip(const char *t);
//!Destructor
~GuiTooltip();
//!Gets the element's current scale
float GetScale();
//!Sets the text of the GuiTooltip element
//!\param t Text
void SetText(const char * t);
//!Constantly called to draw the GuiTooltip
void DrawTooltip();
time_t time1, time2; //!< Tooltip times
protected:
GuiImage leftImage; //!< Tooltip left image
GuiImage tileImage; //!< Tooltip tile image
GuiImage rightImage; //!< Tooltip right image
GuiText *text; //!< Tooltip text
};
//!Display, manage, and manipulate buttons in the GUI. Buttons can have images, icons, text, and sound set (all of which are optional)
@ -656,7 +732,7 @@ class GuiButton : public GuiElement
//!Constructor
//!\param w Width
//!\param h Height
GuiButton(int w, int h);
GuiButton(int w = 0, int h = 0);
//!Destructor
~GuiButton();
//!Sets the button's image
@ -708,8 +784,15 @@ class GuiButton : public GuiElement
//!Sets the sound to play on click
//!\param s Pointer to GuiSound object
void SetSoundClick(GuiSound * s);
//!Sets the tooltip for the button
//!\param t Tooltip
void SetTooltip(GuiTooltip * t);
//!Constantly called to draw the GuiButton
void Draw();
//!Constantly called to draw the GuiButton's tooltip
void DrawTooltip();
//!Resets the text for all contained elements
void ResetText();
//!Constantly called to allow the GuiButton to respond to updated input data
//!\param t Pointer to a GuiTrigger, containing the current input data from PAD/WPAD
void Update(GuiTrigger * t);
@ -729,10 +812,11 @@ class GuiButton : public GuiElement
GuiSound * soundOver; //!< Sound to play for STATE_SELECTED
GuiSound * soundHold; //!< Sound to play for STATE_HELD
GuiSound * soundClick; //!< Sound to play for STATE_CLICKED
GuiTooltip * tooltip; //!< Tooltip to display on over
};
typedef struct _keytype {
char ch, chShift;
unsigned char ch, chShift;
} Key;
//!On-screen keyboard
@ -745,11 +829,18 @@ class GuiKeyboard : public GuiWindow
char kbtextstr[256];
protected:
u32 kbtextmaxlen;
Key keys[4][11];
int shift;
int caps;
GuiText * kbText;
GuiImage * keyTextboxImg;
GuiText * keyEscText;
GuiImage * keyEscImg;
GuiImage * keyEscOverImg;
GuiButton * keyEsc;
GuiText * keyEnterText;
GuiImage * keyEnterImg;
GuiImage * keyEnterOverImg;
GuiButton * keyEnter;
GuiText * keyCapsText;
GuiImage * keyCapsImg;
GuiImage * keyCapsOverImg;
@ -765,10 +856,10 @@ class GuiKeyboard : public GuiWindow
GuiImage * keySpaceImg;
GuiImage * keySpaceOverImg;
GuiButton * keySpace;
GuiButton * keyBtn[4][11];
GuiImage * keyImg[4][11];
GuiImage * keyImgOver[4][11];
GuiText * keyTxt[4][11];
GuiButton * keyBtn[5][12];
GuiImage * keyImg[5][12];
GuiImage * keyImgOver[5][12];
GuiText * keyTxt[5][12];
GuiImageData * keyTextbox;
GuiImageData * key;
GuiImageData * keyOver;
@ -779,6 +870,8 @@ class GuiKeyboard : public GuiWindow
GuiSound * keySoundOver;
GuiSound * keySoundClick;
GuiTrigger * trigA;
GuiTrigger * trigB;
Key keys[5][12]; // two chars = less space than one pointer
};
#endif

View File

@ -1,7 +1,7 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
* Tantric 2009-2010
*
* gui_button.cpp
*
@ -37,6 +37,7 @@ GuiButton::GuiButton(int w, int h)
soundOver = NULL;
soundHold = NULL;
soundClick = NULL;
tooltip = NULL;
selectable = true;
holdable = false;
clickable = true;
@ -121,6 +122,12 @@ void GuiButton::SetSoundClick(GuiSound * snd)
{
soundClick = snd;
}
void GuiButton::SetTooltip(GuiTooltip* t)
{
tooltip = t;
if(t)
tooltip->SetParent(this);
}
/**
* Draw the button on screen
@ -130,28 +137,72 @@ void GuiButton::Draw()
if(!this->IsVisible())
return;
// draw image
if((state == STATE_SELECTED || state == STATE_HELD) && imageOver)
imageOver->Draw();
else if(image)
image->Draw();
// draw icon
if((state == STATE_SELECTED || state == STATE_HELD) && iconOver)
iconOver->Draw();
else if(icon)
icon->Draw();
// draw text
for(int i=0; i<3; i++)
if(state == STATE_SELECTED || state == STATE_HELD)
{
if((state == STATE_SELECTED || state == STATE_HELD) && labelOver[i])
labelOver[i]->Draw();
else if(label[i])
label[i]->Draw();
if(imageOver)
imageOver->Draw();
else if(image) // draw image
image->Draw();
if(iconOver)
iconOver->Draw();
else if(icon) // draw icon
icon->Draw();
// draw text
if(labelOver[0])
labelOver[0]->Draw();
else if(label[0])
label[0]->Draw();
if(labelOver[1])
labelOver[1]->Draw();
else if(label[1])
label[1]->Draw();
if(labelOver[2])
labelOver[2]->Draw();
else if(label[2])
label[2]->Draw();
}
else
{
if(image) // draw image
image->Draw();
if(icon) // draw icon
icon->Draw();
// draw text
if(label[0])
label[0]->Draw();
if(label[1])
label[1]->Draw();
if(label[2])
label[2]->Draw();
}
this->UpdateEffects();
}
void GuiButton::DrawTooltip()
{
if(tooltip)
tooltip->DrawTooltip();
}
void GuiButton::ResetText()
{
for(int i=0; i<3; i++)
{
if(label[i])
label[i]->ResetText();
if(labelOver[i])
labelOver[i]->ResetText();
}
if(tooltip)
tooltip->ResetText();
}
void GuiButton::Update(GuiTrigger * t)
{
if(state == STATE_CLICKED || state == STATE_DISABLED || !t)
@ -204,7 +255,7 @@ void GuiButton::Update(GuiTrigger * t)
if(this->IsClickable())
{
s32 wm_btns, wm_btns_trig, cc_btns, cc_btns_trig;
for(int i=0; i<2; i++)
for(int i=0; i<3; i++)
{
if(trigger[i] && (trigger[i]->chan == -1 || trigger[i]->chan == t->chan))
{
@ -254,7 +305,7 @@ void GuiButton::Update(GuiTrigger * t)
bool held = false;
s32 wm_btns, wm_btns_h, wm_btns_trig, cc_btns, cc_btns_h, cc_btns_trig;
for(int i=0; i<2; i++)
for(int i=0; i<3; i++)
{
if(trigger[i] && (trigger[i]->chan == -1 || trigger[i]->chan == t->chan))
{

View File

@ -1,7 +1,7 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
* Tantric 2009-2010
*
* gui_element.cpp
*
@ -24,11 +24,13 @@ GuiElement::GuiElement()
width = 0;
height = 0;
alpha = 255;
scale = 1;
xscale = 1;
yscale = 1;
state = STATE_DEFAULT;
stateChan = -1;
trigger[0] = NULL;
trigger[1] = NULL;
trigger[2] = NULL;
parentElement = NULL;
rumble = true;
selectable = false;
@ -91,12 +93,13 @@ int GuiElement::GetLeft()
x = pLeft;
break;
case ALIGN_CENTRE:
x = pLeft + (pWidth/2) - (width/2);
x = pLeft + pWidth/2.0 - (width*xscale)/2.0;
break;
case ALIGN_RIGHT:
x = pLeft + pWidth - width;
x = pLeft + pWidth - width*xscale;
break;
}
x += (width*(xscale - 1))/2.0; // correct offset for scaled images
return x + xoffset;
}
@ -121,12 +124,13 @@ int GuiElement::GetTop()
y = pTop;
break;
case ALIGN_MIDDLE:
y = pTop + (pHeight/2) - (height/2);
y = pTop + pHeight/2.0 - (height*yscale)/2.0;
break;
case ALIGN_BOTTOM:
y = pTop + pHeight - height;
y = pTop + pHeight - height*yscale;
break;
}
y += (height*(yscale - 1))/2.0; // correct offset for scaled images
return y + yoffset;
}
@ -204,27 +208,49 @@ void GuiElement::SetAlpha(int a)
int GuiElement::GetAlpha()
{
int a;
int a = alpha;
if(alphaDyn >= 0)
a = alphaDyn;
else
a = alpha;
if(parentElement)
a *= parentElement->GetAlpha()/255.0;
a *= float(parentElement->GetAlpha())/255.0f;
return a;
}
void GuiElement::SetScale(float s)
{
scale = s;
xscale = s;
yscale = s;
}
void GuiElement::SetScaleX(float s)
{
xscale = s;
}
void GuiElement::SetScaleY(float s)
{
yscale = s;
}
void GuiElement::SetScale(int mw, int mh)
{
xscale = 1.0f;
if(width > mw || height > mh)
{
if(width/(height*1.0) > mw/(mh*1.0))
xscale = mw/(width*1.0);
else
xscale = mh/(height*1.0);
}
yscale = xscale;
}
float GuiElement::GetScale()
{
float s = scale * scaleDyn;
float s = xscale * scaleDyn;
if(parentElement)
s *= parentElement->GetScale();
@ -232,6 +258,26 @@ float GuiElement::GetScale()
return s;
}
float GuiElement::GetScaleX()
{
float s = xscale * scaleDyn;
if(parentElement)
s *= parentElement->GetScale();
return s;
}
float GuiElement::GetScaleY()
{
float s = yscale * scaleDyn;
if(parentElement)
s *= parentElement->GetScaleY();
return s;
}
int GuiElement::GetState()
{
return state;
@ -314,7 +360,9 @@ void GuiElement::SetTrigger(GuiTrigger * t)
trigger[0] = t;
else if(!trigger[1])
trigger[1] = t;
else // both were assigned, so we'll just overwrite the first one
else if(!trigger[2])
trigger[2] = t;
else // all were assigned, so we'll just overwrite the first one
trigger[0] = t;
}
@ -352,13 +400,12 @@ void GuiElement::SetEffect(int eff, int amount, int target)
else if(eff & EFFECT_SLIDE_RIGHT)
xoffsetDyn = screenwidth;
}
if(eff & EFFECT_FADE && amount > 0)
if(eff & EFFECT_FADE)
{
alphaDyn = 0;
}
else if(eff & EFFECT_FADE && amount < 0)
{
alphaDyn = alpha;
if(amount > 0)
alphaDyn = 0;
else if(amount < 0)
alphaDyn = alpha;
}
effects |= eff;
@ -474,12 +521,13 @@ void GuiElement::UpdateEffects()
}
if(effects & EFFECT_SCALE)
{
scaleDyn += effectAmount/100.0;
scaleDyn += f32(effectAmount)*0.01f;
f32 effTar100 = f32(effectTarget)*0.01f;
if((effectAmount < 0 && scaleDyn <= effectTarget/100.0)
|| (effectAmount > 0 && scaleDyn >= effectTarget/100.0))
if((effectAmount < 0 && scaleDyn <= effTar100)
|| (effectAmount > 0 && scaleDyn >= effTar100))
{
scaleDyn = effectTarget/100.0;
scaleDyn = effTar100;
effects = 0; // shut off effect
}
}
@ -513,17 +561,22 @@ int GuiElement::GetSelected()
return -1;
}
/**
* Draw an element on screen.
*/
void GuiElement::ResetText()
{
}
void GuiElement::Draw()
{
}
void GuiElement::DrawTooltip()
{
}
bool GuiElement::IsInside(int x, int y)
{
if(x > this->GetLeft() && x < (this->GetLeft()+width)
&& y > this->GetTop() && y < (this->GetTop()+height))
if(unsigned(x - this->GetLeft()) < unsigned(width)
&& unsigned(y - this->GetTop()) < unsigned(height))
return true;
return false;
}

View File

@ -1,7 +1,7 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
* Tantric 2009-2010
*
* gui_image.cpp
*
@ -53,7 +53,7 @@ GuiImage::GuiImage(u8 * img, int w, int h)
GuiImage::GuiImage(int w, int h, GXColor c)
{
image = (u8 *)memalign (32, w * h * 4);
image = (u8 *)memalign (32, w * h << 2);
width = w;
height = h;
imageangle = 0;
@ -66,14 +66,14 @@ GuiImage::GuiImage(int w, int h, GXColor c)
int x, y;
for(y=0; y < h; y++)
for(y=0; y < h; ++y)
{
for(x=0; x < w; x++)
for(x=0; x < w; ++x)
{
this->SetPixel(x, y, c);
}
}
int len = w*h*4;
int len = w * h << 2;
if(len%32) len += (32-len%32);
DCFlushRange(image, len);
}
@ -157,21 +157,24 @@ void GuiImage::SetStripe(int s)
void GuiImage::ColorStripe(int shift)
{
int x, y;
GXColor color;
int x, y=0;
int alt = 0;
int thisHeight = this->GetHeight();
int thisWidth = this->GetWidth();
for(y=0; y < this->GetHeight(); y++)
for(; y < thisHeight; ++y)
{
if(y % 3 == 0)
alt ^= 1;
for(x=0; x < this->GetWidth(); x++)
if(alt)
{
color = GetPixel(x, y);
if(alt)
for(x=0; x < thisWidth; ++x)
{
color = GetPixel(x, y);
if(color.r < 255-shift)
color.r += shift;
else
@ -186,9 +189,15 @@ void GuiImage::ColorStripe(int shift)
color.b = 255;
color.a = 255;
SetPixel(x, y, color);
}
else
}
else
{
for(x=0; x < thisWidth; ++x)
{
color = GetPixel(x, y);
if(color.r > shift)
color.r -= shift;
else
@ -203,8 +212,8 @@ void GuiImage::ColorStripe(int shift)
color.b = 0;
color.a = 255;
SetPixel(x, y, color);
}
SetPixel(x, y, color);
}
}
}
@ -217,26 +226,30 @@ void GuiImage::Draw()
if(!image || !this->IsVisible() || tile == 0)
return;
float currScale = this->GetScale();
float currScaleX = this->GetScaleX();
float currScaleY = this->GetScaleY();
int currLeft = this->GetLeft();
int thisTop = this->GetTop();
if(tile > 0)
{
for(int i=0; i<tile; i++)
Menu_DrawImg(currLeft+width*i, this->GetTop(), width, height, image, imageangle, currScale, currScale, this->GetAlpha());
int alpha = this->GetAlpha();
for(int i=0; i<tile; ++i)
{
Menu_DrawImg(currLeft+width*i, thisTop, width, height, image, imageangle, currScaleX, currScaleY, alpha);
}
}
else
{
// temporary (maybe), used to correct offset for scaled images
if(scale != 1)
currLeft = currLeft - width/2 + (width*scale)/2;
Menu_DrawImg(currLeft, this->GetTop(), width, height, image, imageangle, currScale, currScale, this->GetAlpha());
Menu_DrawImg(currLeft, thisTop, width, height, image, imageangle, currScaleX, currScaleY, this->GetAlpha());
}
if(stripe > 0)
for(int y=0; y < this->GetHeight(); y+=6)
Menu_DrawRectangle(currLeft,this->GetTop()+y,this->GetWidth(),3,(GXColor){0, 0, 0, stripe},1);
{
int thisHeight = this->GetHeight();
int thisWidth = this->GetWidth();
for(int y=0; y < thisHeight; y+=6)
Menu_DrawRectangle(currLeft,thisTop+y,thisWidth,3,(GXColor){0, 0, 0, stripe},1);
}
this->UpdateEffects();
}

View File

@ -1,7 +1,7 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
* Tantric 2009-2010
*
* gui_imagedata.cpp
*
@ -13,47 +13,14 @@
/**
* Constructor for the GuiImageData class.
*/
GuiImageData::GuiImageData(const u8 * i)
GuiImageData::GuiImageData(const u8 * i, int maxw, int maxh)
{
data = NULL;
width = 0;
height = 0;
if(i)
{
PNGUPROP imgProp;
IMGCTX ctx = PNGU_SelectImageFromBuffer(i);
if(!ctx)
return;
int res = PNGU_GetImageProperties(ctx, &imgProp);
if(res == PNGU_OK)
{
int len = imgProp.imgWidth * imgProp.imgHeight * 4;
if(len%32) len += (32-len%32);
data = (u8 *)memalign (32, len);
if(data)
{
res = PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, data, 255);
if(res == PNGU_OK)
{
width = imgProp.imgWidth;
height = imgProp.imgHeight;
DCFlushRange(data, len);
}
else
{
free(data);
data = NULL;
}
}
}
PNGU_ReleaseImageContext (ctx);
}
data = DecodePNG(i, &width, &height, maxw, maxh);
}
/**

View File

@ -1,7 +1,7 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
* Tantric 2009-2010
*
* gui_keyboard.cpp
*
@ -9,21 +9,52 @@
***************************************************************************/
#include "gui.h"
#include <string>
using namespace std;
static char tmptxt[MAX_KEYBOARD_DISPLAY];
static char * GetDisplayText(char * t)
static void str_replace(string &str, char *search, const char *replace)
{
if(!t)
return NULL;
int searchLen = strlen(search);
int replaceLen = strlen(replace);
int len = strlen(t);
string::size_type pos=0;
if(len < MAX_KEYBOARD_DISPLAY)
while ((pos=str.find(search, pos)) != string::npos)
{
str.erase(pos, searchLen);
str.insert(pos, replace);
pos += replaceLen;
}
}
static char * GetDisplayText(char * t, int max)
{
if(!t || t[0] == 0)
return t;
strncpy(tmptxt, &t[len-MAX_KEYBOARD_DISPLAY], MAX_KEYBOARD_DISPLAY);
tmptxt[MAX_KEYBOARD_DISPLAY-1] = 0;
string tempStr(t);
char txt[2] = { 0, 0 };
txt[0] = 13; str_replace(tempStr, txt, "<ENTER>");
txt[0] = 27; str_replace(tempStr, txt, "<ESC>");
txt[0] = 14; str_replace(tempStr, txt, "<F1>");
txt[0] = 15; str_replace(tempStr, txt, "<F2>");
txt[0] = 16; str_replace(tempStr, txt, "<F3>");
txt[0] = 17; str_replace(tempStr, txt, "<F4>");
txt[0] = 18; str_replace(tempStr, txt, "<F5>");
txt[0] = 19; str_replace(tempStr, txt, "<F6>");
txt[0] = 20; str_replace(tempStr, txt, "<F7>");
txt[0] = 21; str_replace(tempStr, txt, "<F8>");
txt[0] = 22; str_replace(tempStr, txt, "<F9>");
txt[0] = 23; str_replace(tempStr, txt, "<F10>");
txt[0] = 24; str_replace(tempStr, txt, "<F11>");
txt[0] = 25; str_replace(tempStr, txt, "<F12>");
int s = tempStr.length()-MAX_KEYBOARD_DISPLAY;
if(s < 0) s = 0;
snprintf(tmptxt, MAX_KEYBOARD_DISPLAY, "%s", &(tempStr.c_str()[s]));
return &tmptxt[0];
}
@ -33,8 +64,8 @@ static char * GetDisplayText(char * t)
GuiKeyboard::GuiKeyboard(char * t, u32 max)
{
width = 540;
height = 400;
width = 610;
height = 440;
shift = 0;
caps = 0;
selectable = true;
@ -45,8 +76,23 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max)
kbtextstr[max] = 0;
kbtextmaxlen = max;
Key thekeys[4][11] = {
Key thekeys[5][12] = {
{
{14,0}, // F1
{15,0}, // F2
{16,0}, // F3
{17,0}, // F4
{18,0}, // F5
{19,0}, // F6
{20,0}, // F7
{21,0}, // F8
{22,0}, // F9
{23,0}, // F10
{24,0}, // F11
{25,0}, // F12
},
{
{'`','~'},
{'1','!'},
{'2','@'},
{'3','#'},
@ -57,7 +103,7 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max)
{'8','*'},
{'9','('},
{'0',')'},
{'\0','\0'}
{'-','_'}
},
{
{'q','Q'},
@ -70,7 +116,8 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max)
{'i','I'},
{'o','O'},
{'p','P'},
{'-','_'}
{'[','{'},
{']','}'}
},
{
{'a','A'},
@ -83,7 +130,8 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max)
{'k','K'},
{'l','L'},
{';',':'},
{'\'','"'}
{'\'','"'},
{'\\','|'}
},
{
@ -97,6 +145,7 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max)
{',','<'},
{'.','>'},
{'/','?'},
{'\0','\0'},
{'\0','\0'}
}
};
@ -105,12 +154,12 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max)
keyTextbox = new GuiImageData(keyboard_textbox_png);
keyTextboxImg = new GuiImage(keyTextbox);
keyTextboxImg->SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
keyTextboxImg->SetPosition(0, 0);
keyTextboxImg->SetPosition(0, 20);
this->Append(keyTextboxImg);
kbText = new GuiText(GetDisplayText(kbtextstr), 22, (GXColor){0, 0, 0, 0xff});
kbText = new GuiText(GetDisplayText(kbtextstr, max), 22, (GXColor){0, 0, 0, 0xff});
kbText->SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
kbText->SetPosition(0, 13);
kbText->SetPosition(0, 33);
this->Append(kbText);
key = new GuiImageData(keyboard_key_png);
@ -124,6 +173,38 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max)
keySoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, SOUND_PCM);
trigA = new GuiTrigger;
trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
trigB = new GuiTrigger;
trigB->SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B);
int yoff = 80;
keyEscImg = new GuiImage(keyMedium);
keyEscOverImg = new GuiImage(keyMediumOver);
keyEscText = new GuiText("Esc", 22, (GXColor){0, 0, 0, 0xff});
keyEsc = new GuiButton(keyMedium->GetWidth(), keyMedium->GetHeight());
keyEsc->SetImage(keyEscImg);
keyEsc->SetImageOver(keyEscOverImg);
keyEsc->SetLabel(keyEscText);
keyEsc->SetSoundOver(keySoundOver);
keyEsc->SetSoundClick(keySoundClick);
keyEsc->SetTrigger(trigA);
keyEsc->SetPosition(0, yoff);
keyEsc->SetEffectGrow();
this->Append(keyEsc);
keyEnterImg = new GuiImage(keyMedium);
keyEnterOverImg = new GuiImage(keyMediumOver);
keyEnterText = new GuiText("Enter", 22, (GXColor){0, 0, 0, 0xff});
keyEnter = new GuiButton(keyMedium->GetWidth(), keyMedium->GetHeight());
keyEnter->SetImage(keyEnterImg);
keyEnter->SetImageOver(keyEnterOverImg);
keyEnter->SetLabel(keyEnterText);
keyEnter->SetSoundOver(keySoundOver);
keyEnter->SetSoundClick(keySoundClick);
keyEnter->SetTrigger(trigA);
keyEnter->SetPosition(12*42+18, 4*42+yoff);
keyEnter->SetEffectGrow();
this->Append(keyEnter);
keyBackImg = new GuiImage(keyMedium);
keyBackOverImg = new GuiImage(keyMediumOver);
@ -135,7 +216,8 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max)
keyBack->SetSoundOver(keySoundOver);
keyBack->SetSoundClick(keySoundClick);
keyBack->SetTrigger(trigA);
keyBack->SetPosition(10*42+40, 0*42+80);
keyBack->SetTrigger(trigB);
keyBack->SetPosition(11*42+40, 1*42+yoff);
keyBack->SetEffectGrow();
this->Append(keyBack);
@ -149,7 +231,7 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max)
keyCaps->SetSoundOver(keySoundOver);
keyCaps->SetSoundClick(keySoundClick);
keyCaps->SetTrigger(trigA);
keyCaps->SetPosition(0, 2*42+80);
keyCaps->SetPosition(0, 3*42+yoff);
keyCaps->SetEffectGrow();
this->Append(keyCaps);
@ -163,7 +245,7 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max)
keyShift->SetSoundOver(keySoundOver);
keyShift->SetSoundClick(keySoundClick);
keyShift->SetTrigger(trigA);
keyShift->SetPosition(21, 3*42+80);
keyShift->SetPosition(21, 4*42+yoff);
keyShift->SetEffectGrow();
this->Append(keyShift);
@ -175,23 +257,41 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max)
keySpace->SetSoundOver(keySoundOver);
keySpace->SetSoundClick(keySoundClick);
keySpace->SetTrigger(trigA);
keySpace->SetPosition(0, 4*42+80);
keySpace->SetPosition(0, 5*42+yoff);
keySpace->SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
keySpace->SetEffectGrow();
this->Append(keySpace);
char txt[2] = { 0, 0 };
for(int i=0; i<4; i++)
for(int i=0; i<5; i++)
{
for(int j=0; j<11; j++)
for(int j=0; j<12; j++)
{
if(keys[i][j].ch != '\0')
{
txt[0] = keys[i][j].ch;
keyImg[i][j] = new GuiImage(key);
keyImgOver[i][j] = new GuiImage(keyOver);
keyTxt[i][j] = new GuiText(txt, 22, (GXColor){0, 0, 0, 0xff});
switch(keys[i][j].ch)
{
case 14: keyTxt[i][j] = new GuiText("F1", 22, (GXColor){0, 0, 0, 0xff}); break;
case 15: keyTxt[i][j] = new GuiText("F2", 22, (GXColor){0, 0, 0, 0xff}); break;
case 16: keyTxt[i][j] = new GuiText("F3", 22, (GXColor){0, 0, 0, 0xff}); break;
case 17: keyTxt[i][j] = new GuiText("F4", 22, (GXColor){0, 0, 0, 0xff}); break;
case 18: keyTxt[i][j] = new GuiText("F5", 22, (GXColor){0, 0, 0, 0xff}); break;
case 19: keyTxt[i][j] = new GuiText("F6", 22, (GXColor){0, 0, 0, 0xff}); break;
case 20: keyTxt[i][j] = new GuiText("F7", 22, (GXColor){0, 0, 0, 0xff}); break;
case 21: keyTxt[i][j] = new GuiText("F8", 22, (GXColor){0, 0, 0, 0xff}); break;
case 22: keyTxt[i][j] = new GuiText("F9", 22, (GXColor){0, 0, 0, 0xff}); break;
case 23: keyTxt[i][j] = new GuiText("F10", 22, (GXColor){0, 0, 0, 0xff}); break;
case 24: keyTxt[i][j] = new GuiText("F11", 22, (GXColor){0, 0, 0, 0xff}); break;
case 25: keyTxt[i][j] = new GuiText("F12", 22, (GXColor){0, 0, 0, 0xff}); break;
default:
keyTxt[i][j] = new GuiText(txt, 22, (GXColor){0, 0, 0, 0xff});
break;
}
keyTxt[i][j]->SetAlignment(ALIGN_CENTRE, ALIGN_BOTTOM);
keyTxt[i][j]->SetPosition(0, -10);
keyBtn[i][j] = new GuiButton(key->GetWidth(), key->GetHeight());
@ -201,7 +301,16 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max)
keyBtn[i][j]->SetSoundClick(keySoundClick);
keyBtn[i][j]->SetTrigger(trigA);
keyBtn[i][j]->SetLabel(keyTxt[i][j]);
keyBtn[i][j]->SetPosition(j*42+21*i+40, i*42+80);
int stagger;
switch(i)
{
case 0: stagger = 42; break;
case 1: stagger = -42; break;
default: stagger = 21*(i-1); break;
}
keyBtn[i][j]->SetPosition(j*42+stagger+40, i*42+yoff);
keyBtn[i][j]->SetEffectGrow();
this->Append(keyBtn[i][j]);
}
@ -217,6 +326,14 @@ GuiKeyboard::~GuiKeyboard()
delete kbText;
delete keyTextbox;
delete keyTextboxImg;
delete keyEscText;
delete keyEscImg;
delete keyEscOverImg;
delete keyEsc;
delete keyEnterText;
delete keyEnterImg;
delete keyEnterOverImg;
delete keyEnter;
delete keyCapsText;
delete keyCapsImg;
delete keyCapsOverImg;
@ -242,9 +359,9 @@ GuiKeyboard::~GuiKeyboard()
delete keySoundClick;
delete trigA;
for(int i=0; i<4; i++)
for(int i=0; i<5; i++)
{
for(int j=0; j<11; j++)
for(int j=0; j<12; j++)
{
if(keys[i][j].ch != '\0')
{
@ -270,19 +387,37 @@ void GuiKeyboard::Update(GuiTrigger * t)
bool update = false;
if(keySpace->GetState() == STATE_CLICKED)
if(keyEsc->GetState() == STATE_CLICKED)
{
if(strlen(kbtextstr) < kbtextmaxlen)
{
kbtextstr[strlen(kbtextstr)] = 27; // Esc key code
kbText->SetText(GetDisplayText(kbtextstr, kbtextmaxlen));
}
keyEsc->SetState(STATE_SELECTED, t->chan);
}
else if(keyEnter->GetState() == STATE_CLICKED)
{
if(strlen(kbtextstr) < kbtextmaxlen)
{
kbtextstr[strlen(kbtextstr)] = 13; // Enter key code
kbText->SetText(GetDisplayText(kbtextstr, kbtextmaxlen));
}
keyEnter->SetState(STATE_SELECTED, t->chan);
}
else if(keySpace->GetState() == STATE_CLICKED)
{
if(strlen(kbtextstr) < kbtextmaxlen)
{
kbtextstr[strlen(kbtextstr)] = ' ';
kbText->SetText(kbtextstr);
kbText->SetText(GetDisplayText(kbtextstr, kbtextmaxlen));
}
keySpace->SetState(STATE_SELECTED, t->chan);
}
else if(keyBack->GetState() == STATE_CLICKED)
{
kbtextstr[strlen(kbtextstr)-1] = 0;
kbText->SetText(GetDisplayText(kbtextstr));
kbText->SetText(GetDisplayText(kbtextstr, kbtextmaxlen));
keyBack->SetState(STATE_SELECTED, t->chan);
}
else if(keyShift->GetState() == STATE_CLICKED)
@ -302,13 +437,13 @@ void GuiKeyboard::Update(GuiTrigger * t)
startloop:
for(int i=0; i<4; i++)
for(int i=0; i<5; i++)
{
for(int j=0; j<11; j++)
for(int j=0; j<12; j++)
{
if(keys[i][j].ch != '\0')
{
if(update)
if(update && keys[i][j].ch > 31)
{
if(shift || caps)
txt[0] = keys[i][j].chShift;
@ -331,7 +466,7 @@ void GuiKeyboard::Update(GuiTrigger * t)
kbtextstr[strlen(kbtextstr)] = keys[i][j].ch;
}
}
kbText->SetText(GetDisplayText(kbtextstr));
kbText->SetText(GetDisplayText(kbtextstr, kbtextmaxlen));
keyBtn[i][j]->SetState(STATE_SELECTED, t->chan);
if(shift)

View File

@ -1,7 +1,7 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
* Tantric 2009-2010
*
* gui_sound.cpp
*

View File

@ -1,7 +1,7 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
* Tantric 2009-2010
*
* gui_text.cpp
*
@ -10,13 +10,13 @@
#include "gui.h"
static GXColor presetColor = (GXColor){255, 255, 255, 255};
static int currentSize = 0;
static int presetSize = 0;
static int presetMaxWidth = 0;
static int presetAlignmentHor = 0;
static int presetAlignmentVert = 0;
static u16 presetStyle = 0;
static GXColor presetColor = (GXColor){255, 255, 255, 255};
#define TEXT_SCROLL_DELAY 8
#define TEXT_SCROLL_INITIAL_DELAY 6
@ -34,7 +34,7 @@ GuiText::GuiText(const char * t, int s, GXColor c)
style = FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE;
maxWidth = 0;
wrap = false;
textDyn = NULL;
textDynNum = 0;
textScroll = SCROLL_NONE;
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
@ -48,6 +48,9 @@ GuiText::GuiText(const char * t, int s, GXColor c)
origText = strdup(t);
text = charToWideChar(t);
}
for(int i=0; i < 20; i++)
textDyn[i] = NULL;
}
/**
@ -63,7 +66,7 @@ GuiText::GuiText(const char * t)
style = presetStyle;
maxWidth = presetMaxWidth;
wrap = false;
textDyn = NULL;
textDynNum = 0;
textScroll = SCROLL_NONE;
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
@ -77,6 +80,9 @@ GuiText::GuiText(const char * t)
origText = strdup(t);
text = charToWideChar(t);
}
for(int i=0; i < 20; i++)
textDyn[i] = NULL;
}
/**
@ -88,8 +94,13 @@ GuiText::~GuiText()
free(origText);
if(text)
delete[] text;
if(textDyn)
delete[] textDyn;
if(textDynNum > 0)
{
for(int i=0; i < textDynNum; i++)
if(textDyn[i])
delete[] textDyn[i];
}
}
void GuiText::SetText(const char * t)
@ -98,12 +109,17 @@ void GuiText::SetText(const char * t)
free(origText);
if(text)
delete[] text;
if(textDyn)
delete[] textDyn;
if(textDynNum > 0)
{
for(int i=0; i < textDynNum; i++)
if(textDyn[i])
delete[] textDyn[i];
}
origText = NULL;
text = NULL;
textDyn = NULL;
textDynNum = 0;
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
@ -114,6 +130,38 @@ void GuiText::SetText(const char * t)
}
}
void GuiText::SetWText(wchar_t * t)
{
if(origText)
free(origText);
if(text)
delete[] text;
if(textDynNum > 0)
{
for(int i=0; i < textDynNum; i++)
if(textDyn[i])
delete[] textDyn[i];
}
origText = NULL;
text = NULL;
textDynNum = 0;
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
if(t)
text = wcsdup(t);
}
int GuiText::GetLength()
{
if(!text)
return 0;
return wcslen(text);
}
void GuiText::SetPresets(int sz, GXColor c, int w, u16 s, int h, int v)
{
presetSize = sz;
@ -132,12 +180,51 @@ void GuiText::SetFontSize(int s)
void GuiText::SetMaxWidth(int width)
{
maxWidth = width;
for(int i=0; i < textDynNum; i++)
{
if(textDyn[i])
{
delete[] textDyn[i];
textDyn[i] = NULL;
}
}
textDynNum = 0;
}
int GuiText::GetTextWidth()
{
if(!text)
return 0;
if(currentSize != size)
{
ChangeFontSize(size);
if(!fontSystem[size])
fontSystem[size] = new FreeTypeGX(size);
currentSize = size;
}
return fontSystem[size]->getWidth(text);
}
void GuiText::SetWrap(bool w, int width)
{
wrap = w;
maxWidth = width;
for(int i=0; i < textDynNum; i++)
{
if(textDyn[i])
{
delete[] textDyn[i];
textDyn[i] = NULL;
}
}
textDynNum = 0;
}
void GuiText::SetScroll(int s)
@ -145,11 +232,17 @@ void GuiText::SetScroll(int s)
if(textScroll == s)
return;
if(textDyn)
for(int i=0; i < textDynNum; i++)
{
delete[] textDyn;
textDyn = NULL;
if(textDyn[i])
{
delete[] textDyn[i];
textDyn[i] = NULL;
}
}
textDynNum = 0;
textScroll = s;
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
@ -200,6 +293,28 @@ void GuiText::SetAlignment(int hor, int vert)
alignmentVert = vert;
}
void GuiText::ResetText()
{
if(!origText)
return;
if(text)
delete[] text;
text = charToWideChar(origText);
for(int i=0; i < textDynNum; i++)
{
if(textDyn[i])
{
delete[] textDyn[i];
textDyn[i] = NULL;
}
}
textDynNum = 0;
currentSize = 0;
}
/**
* Draw the text on screen
*/
@ -227,122 +342,138 @@ void GuiText::Draw()
currentSize = newSize;
}
if(maxWidth > 0)
if(maxWidth == 0)
{
char * tmpText = strdup(origText);
u8 maxChar = (maxWidth*2.0) / newSize;
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop(), text, c, style);
this->UpdateEffects();
return;
}
if(!textDyn)
u32 textlen = wcslen(text);
if(wrap)
{
if(textDynNum == 0)
{
if(strlen(tmpText) > maxChar)
tmpText[maxChar] = 0;
textDyn = charToWideChar(tmpText);
u32 n = 0, ch = 0;
int linenum = 0;
int lastSpace = -1;
int lastSpaceIndex = -1;
while(ch < textlen && linenum < 20)
{
if(n == 0)
textDyn[linenum] = new wchar_t[textlen + 1];
textDyn[linenum][n] = text[ch];
textDyn[linenum][n+1] = 0;
if(text[ch] == ' ' || ch == textlen-1)
{
if(fontSystem[currentSize]->getWidth(textDyn[linenum]) > maxWidth)
{
if(lastSpace >= 0)
{
textDyn[linenum][lastSpaceIndex] = 0; // discard space, and everything after
ch = lastSpace; // go backwards to the last space
lastSpace = -1; // we have used this space
lastSpaceIndex = -1;
}
++linenum;
n = -1;
}
else if(ch == textlen-1)
{
++linenum;
}
}
if(text[ch] == ' ' && n >= 0)
{
lastSpace = ch;
lastSpaceIndex = n;
}
++ch;
++n;
}
textDynNum = linenum;
}
int lineheight = newSize + 6;
int voffset = 0;
if(alignmentVert == ALIGN_MIDDLE)
voffset = (lineheight >> 1) * (1-textDynNum);
int left = this->GetLeft();
int top = this->GetTop() + voffset;
for(int i=0; i < textDynNum; ++i)
fontSystem[currentSize]->drawText(left, top+i*lineheight, textDyn[i], c, style);
}
else
{
if(textDynNum == 0)
{
textDynNum = 1;
textDyn[0] = wcsdup(text);
int len = wcslen(textDyn[0]);
while(fontSystem[currentSize]->getWidth(textDyn[0]) > maxWidth)
textDyn[0][--len] = 0;
}
if(textScroll == SCROLL_HORIZONTAL)
{
int textlen = strlen(origText);
if(textlen > maxChar && (FrameTimer % textScrollDelay == 0))
if(fontSystem[currentSize]->getWidth(text) > maxWidth && (FrameTimer % textScrollDelay == 0))
{
if(textScrollInitialDelay)
{
textScrollInitialDelay--;
--textScrollInitialDelay;
}
else
{
textScrollPos++;
if(textScrollPos > textlen-1)
++textScrollPos;
if((u32)textScrollPos > textlen-1)
{
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
}
strncpy(tmpText, &origText[textScrollPos], maxChar-1);
tmpText[maxChar-1] = 0;
wcscpy(textDyn[0], &text[textScrollPos]);
u32 dynlen = wcslen(textDyn[0]);
int dynlen = strlen(tmpText);
if(dynlen+2 < maxChar)
if(dynlen+2 < textlen)
{
tmpText[dynlen] = ' ';
tmpText[dynlen+1] = ' ';
strncat(&tmpText[dynlen+2], origText, maxChar - dynlen - 2);
textDyn[0][dynlen] = ' ';
textDyn[0][dynlen+1] = ' ';
textDyn[0][dynlen+2] = 0;
dynlen += 2;
}
if(textDyn) delete[] textDyn;
textDyn = charToWideChar(tmpText);
}
}
if(textDyn)
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop(), textDyn, c, style);
}
else if(wrap)
{
int lineheight = newSize + 6;
int txtlen = wcslen(text);
int i = 0;
int ch = 0;
int linenum = 0;
int lastSpace = -1;
int lastSpaceIndex = -1;
wchar_t * textrow[20];
while(ch < txtlen)
{
if(i == 0)
textrow[linenum] = new wchar_t[txtlen + 1];
textrow[linenum][i] = text[ch];
textrow[linenum][i+1] = 0;
if(text[ch] == ' ' || ch == txtlen-1)
{
if(wcslen(textrow[linenum]) >= maxChar)
if(fontSystem[currentSize]->getWidth(textDyn[0]) > maxWidth)
{
if(lastSpace >= 0)
while(fontSystem[currentSize]->getWidth(textDyn[0]) > maxWidth)
textDyn[0][--dynlen] = 0;
}
else
{
int i = 0;
while(fontSystem[currentSize]->getWidth(textDyn[0]) < maxWidth && dynlen+1 < textlen)
{
textrow[linenum][lastSpaceIndex] = 0; // discard space, and everything after
ch = lastSpace; // go backwards to the last space
lastSpace = -1; // we have used this space
lastSpaceIndex = -1;
textDyn[0][dynlen] = text[i++];
textDyn[0][++dynlen] = 0;
}
linenum++;
i = -1;
}
else if(ch == txtlen-1)
{
linenum++;
if(fontSystem[currentSize]->getWidth(textDyn[0]) > maxWidth)
textDyn[0][dynlen-2] = 0;
else
textDyn[0][dynlen-1] = 0;
}
}
if(text[ch] == ' ' && i >= 0)
{
lastSpace = ch;
lastSpaceIndex = i;
}
ch++;
i++;
}
int voffset = 0;
if(alignmentVert == ALIGN_MIDDLE)
voffset = -(lineheight*linenum)/2 + lineheight/2;
for(i=0; i < linenum; i++)
{
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop()+voffset+i*lineheight, textrow[i], c, style);
delete[] textrow[i];
}
}
else
{
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop(), textDyn, c, style);
}
free(tmpText);
}
else
{
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop(), text, c, style);
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop(), textDyn[0], c, style);
}
this->UpdateEffects();
}

View File

@ -1,7 +1,7 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
* Tantric 2009-2010
*
* gui_trigger.cpp
*
@ -9,8 +9,12 @@
***************************************************************************/
#include "gui.h"
#include <ogc/lwp_watchdog.h>
#include <gctypes.h>
static int scrollDelay = 0;
static u64 prev[4];
static u64 now[4];
static u32 delay[4];
/**
* Constructor for the GuiTrigger class.
@ -87,7 +91,7 @@ void GuiTrigger::SetButtonOnlyInFocusTrigger(s32 ch, u32 wiibtns, u16 gcbtns)
* Get X/Y value from Wii Joystick (classic, nunchuk) input
***************************************************************************/
s8 GuiTrigger::WPAD_Stick(u8 right, int axis)
s8 GuiTrigger::WPAD_Stick(u8 stick, int axis)
{
float mag = 0.0;
float ang = 0.0;
@ -96,7 +100,7 @@ s8 GuiTrigger::WPAD_Stick(u8 right, int axis)
{
case WPAD_EXP_NUNCHUK:
case WPAD_EXP_GUITARHERO3:
if (right == 0)
if (stick == 0)
{
mag = wpad->exp.nunchuk.js.mag;
ang = wpad->exp.nunchuk.js.ang;
@ -104,7 +108,7 @@ s8 GuiTrigger::WPAD_Stick(u8 right, int axis)
break;
case WPAD_EXP_CLASSIC:
if (right == 0)
if (stick == 0)
{
mag = wpad->exp.classic.ljs.mag;
ang = wpad->exp.classic.ljs.ang;
@ -133,6 +137,16 @@ s8 GuiTrigger::WPAD_Stick(u8 right, int axis)
return (s8)(val * 128.0f);
}
s8 GuiTrigger::WPAD_StickX(u8 stick)
{
return WPAD_Stick(stick, 0);
}
s8 GuiTrigger::WPAD_StickY(u8 stick)
{
return WPAD_Stick(stick, 1);
}
bool GuiTrigger::Left()
{
u32 wiibtn = WPAD_BUTTON_LEFT;
@ -140,24 +154,28 @@ bool GuiTrigger::Left()
if((wpad->btns_d | wpad->btns_h) & (wiibtn | WPAD_CLASSIC_BUTTON_LEFT)
|| (pad.btns_d | pad.btns_h) & PAD_BUTTON_LEFT
|| pad.stickX < -PADCAL
|| WPAD_Stick(0,0) < -PADCAL)
|| WPAD_StickX(0) < -PADCAL)
{
if(wpad->btns_d & (wiibtn | WPAD_CLASSIC_BUTTON_LEFT)
|| pad.btns_d & PAD_BUTTON_LEFT)
{
scrollDelay = SCROLL_INITIAL_DELAY; // reset scroll delay.
prev[chan] = gettime();
delay[chan] = SCROLL_DELAY_INITIAL; // reset scroll delay
return true;
}
else if(scrollDelay == 0)
now[chan] = gettime();
if(diff_usec(prev[chan], now[chan]) > delay[chan])
{
scrollDelay = SCROLL_LOOP_DELAY;
prev[chan] = now[chan];
if(delay[chan] == SCROLL_DELAY_INITIAL)
delay[chan] = SCROLL_DELAY_LOOP;
else if(delay[chan] > SCROLL_DELAY_DECREASE)
delay[chan] -= SCROLL_DELAY_DECREASE;
return true;
}
else
{
if(scrollDelay > 0)
scrollDelay--;
}
}
return false;
}
@ -169,24 +187,28 @@ bool GuiTrigger::Right()
if((wpad->btns_d | wpad->btns_h) & (wiibtn | WPAD_CLASSIC_BUTTON_RIGHT)
|| (pad.btns_d | pad.btns_h) & PAD_BUTTON_RIGHT
|| pad.stickX > PADCAL
|| WPAD_Stick(0,0) > PADCAL)
|| WPAD_StickX(0) > PADCAL)
{
if(wpad->btns_d & (wiibtn | WPAD_CLASSIC_BUTTON_RIGHT)
|| pad.btns_d & PAD_BUTTON_RIGHT)
{
scrollDelay = SCROLL_INITIAL_DELAY; // reset scroll delay.
prev[chan] = gettime();
delay[chan] = SCROLL_DELAY_INITIAL; // reset scroll delay
return true;
}
else if(scrollDelay == 0)
now[chan] = gettime();
if(diff_usec(prev[chan], now[chan]) > delay[chan])
{
scrollDelay = SCROLL_LOOP_DELAY;
prev[chan] = now[chan];
if(delay[chan] == SCROLL_DELAY_INITIAL)
delay[chan] = SCROLL_DELAY_LOOP;
else if(delay[chan] > SCROLL_DELAY_DECREASE)
delay[chan] -= SCROLL_DELAY_DECREASE;
return true;
}
else
{
if(scrollDelay > 0)
scrollDelay--;
}
}
return false;
}
@ -198,24 +220,28 @@ bool GuiTrigger::Up()
if((wpad->btns_d | wpad->btns_h) & (wiibtn | WPAD_CLASSIC_BUTTON_UP)
|| (pad.btns_d | pad.btns_h) & PAD_BUTTON_UP
|| pad.stickY > PADCAL
|| WPAD_Stick(0,1) > PADCAL)
|| WPAD_StickY(0) > PADCAL)
{
if(wpad->btns_d & (wiibtn | WPAD_CLASSIC_BUTTON_UP)
|| pad.btns_d & PAD_BUTTON_UP)
{
scrollDelay = SCROLL_INITIAL_DELAY; // reset scroll delay.
prev[chan] = gettime();
delay[chan] = SCROLL_DELAY_INITIAL; // reset scroll delay
return true;
}
else if(scrollDelay == 0)
now[chan] = gettime();
if(diff_usec(prev[chan], now[chan]) > delay[chan])
{
scrollDelay = SCROLL_LOOP_DELAY;
prev[chan] = now[chan];
if(delay[chan] == SCROLL_DELAY_INITIAL)
delay[chan] = SCROLL_DELAY_LOOP;
else if(delay[chan] > SCROLL_DELAY_DECREASE)
delay[chan] -= SCROLL_DELAY_DECREASE;
return true;
}
else
{
if(scrollDelay > 0)
scrollDelay--;
}
}
return false;
}
@ -227,24 +253,28 @@ bool GuiTrigger::Down()
if((wpad->btns_d | wpad->btns_h) & (wiibtn | WPAD_CLASSIC_BUTTON_DOWN)
|| (pad.btns_d | pad.btns_h) & PAD_BUTTON_DOWN
|| pad.stickY < -PADCAL
|| WPAD_Stick(0,1) < -PADCAL)
|| WPAD_StickY(0) < -PADCAL)
{
if(wpad->btns_d & (wiibtn | WPAD_CLASSIC_BUTTON_DOWN)
|| pad.btns_d & PAD_BUTTON_DOWN)
{
scrollDelay = SCROLL_INITIAL_DELAY; // reset scroll delay.
prev[chan] = gettime();
delay[chan] = SCROLL_DELAY_INITIAL; // reset scroll delay
return true;
}
else if(scrollDelay == 0)
now[chan] = gettime();
if(diff_usec(prev[chan], now[chan]) > delay[chan])
{
scrollDelay = SCROLL_LOOP_DELAY;
prev[chan] = now[chan];
if(delay[chan] == SCROLL_DELAY_INITIAL)
delay[chan] = SCROLL_DELAY_LOOP;
else if(delay[chan] > SCROLL_DELAY_DECREASE)
delay[chan] -= SCROLL_DELAY_DECREASE;
return true;
}
else
{
if(scrollDelay > 0)
scrollDelay--;
}
}
return false;
}

View File

@ -1,7 +1,7 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
* Tantric 2009-2010
*
* gui_window.cpp
*
@ -53,7 +53,8 @@ void GuiWindow::Remove(GuiElement* e)
if (e == NULL)
return;
for (u8 i = 0; i < _elements.size(); i++)
u32 elemSize = _elements.size();
for (u32 i = 0; i < elemSize; ++i)
{
if(e == _elements.at(i))
{
@ -68,6 +69,18 @@ void GuiWindow::RemoveAll()
_elements.clear();
}
bool GuiWindow::Find(GuiElement* e)
{
if (e == NULL)
return false;
u32 elemSize = _elements.size();
for (u32 i = 0; i < elemSize; ++i)
if(e == _elements.at(i))
return true;
return false;
}
GuiElement* GuiWindow::GetGuiElementAt(u32 index) const
{
if (index >= _elements.size())
@ -85,7 +98,8 @@ void GuiWindow::Draw()
if(_elements.size() == 0 || !this->IsVisible())
return;
for (u8 i = 0; i < _elements.size(); i++)
u32 elemSize = _elements.size();
for (u32 i = 0; i < elemSize; ++i)
{
try { _elements.at(i)->Draw(); }
catch (const std::exception& e) { }
@ -97,12 +111,26 @@ void GuiWindow::Draw()
Menu_DrawRectangle(0,0,screenwidth,screenheight,(GXColor){0xbe, 0xca, 0xd5, 0x70},1);
}
void GuiWindow::DrawTooltip()
{
if(_elements.size() == 0 || !this->IsVisible())
return;
u32 elemSize = _elements.size();
for (u32 i = 0; i < elemSize; i++)
{
try { _elements.at(i)->DrawTooltip(); }
catch (const std::exception& e) { }
}
}
void GuiWindow::ResetState()
{
if(state != STATE_DISABLED)
state = STATE_DEFAULT;
for (u8 i = 0; i < _elements.size(); i++)
u32 elemSize = _elements.size();
for (u32 i = 0; i < elemSize; ++i)
{
try { _elements.at(i)->ResetState(); }
catch (const std::exception& e) { }
@ -113,7 +141,8 @@ void GuiWindow::SetState(int s)
{
state = s;
for (u8 i = 0; i < _elements.size(); i++)
u32 elemSize = _elements.size();
for (u32 i = 0; i < elemSize; ++i)
{
try { _elements.at(i)->SetState(s); }
catch (const std::exception& e) { }
@ -124,7 +153,8 @@ void GuiWindow::SetVisible(bool v)
{
visible = v;
for (u8 i = 0; i < _elements.size(); i++)
u32 elemSize = _elements.size();
for (u32 i = 0; i < elemSize; ++i)
{
try { _elements.at(i)->SetVisible(v); }
catch (const std::exception& e) { }
@ -146,7 +176,8 @@ void GuiWindow::ChangeFocus(GuiElement* e)
if(parentElement)
return; // this is only intended for the main window
for (u8 i = 0; i < _elements.size(); i++)
u32 elemSize = _elements.size();
for (u32 i = 0; i < elemSize; ++i)
{
if(e == _elements.at(i))
_elements.at(i)->SetFocus(1);
@ -162,10 +193,12 @@ void GuiWindow::ToggleFocus(GuiTrigger * t)
int found = -1;
int newfocus = -1;
u8 i;
int i;
int elemSize = _elements.size();
// look for currently in focus element
for (i = 0; i < _elements.size(); i++)
for (i = 0; i < elemSize; ++i)
{
try
{
@ -181,7 +214,7 @@ void GuiWindow::ToggleFocus(GuiTrigger * t)
// element with focus not found, try to give focus
if(found == -1)
{
for (i = 0; i < _elements.size(); i++)
for (i = 0; i < elemSize; ++i)
{
try
{
@ -198,7 +231,7 @@ void GuiWindow::ToggleFocus(GuiTrigger * t)
else if(t->wpad->btns_d & (WPAD_BUTTON_1 | WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B)
|| t->pad.btns_d & PAD_BUTTON_B)
{
for (i = found; i < _elements.size(); i++)
for (i = found; i < elemSize; ++i)
{
try
{
@ -215,7 +248,7 @@ void GuiWindow::ToggleFocus(GuiTrigger * t)
if(newfocus == -1)
{
for (i = 0; i < found; i++)
for (i = 0; i < found; ++i)
{
try
{
@ -236,13 +269,14 @@ int GuiWindow::GetSelected()
{
// find selected element
int found = -1;
for (u8 i = 0; i < _elements.size(); i++)
u32 elemSize = _elements.size();
for (u32 i = 0; i < elemSize; ++i)
{
try
{
if(_elements.at(i)->GetState() == STATE_SELECTED)
{
found = i;
found = int(i);
break;
}
}
@ -258,7 +292,8 @@ void GuiWindow::MoveSelectionHor(int dir)
int found = -1;
u16 left = 0;
u16 top = 0;
u8 i = 0;
u32 i;
u32 elemSize = _elements.size();
int selected = this->GetSelected();
@ -268,8 +303,9 @@ void GuiWindow::MoveSelectionHor(int dir)
top = _elements.at(selected)->GetTop();
}
// look for a button on the same row, to the left/right
for (i = 0; i < _elements.size(); i++)
for (i = 0; i < elemSize; ++i)
{
try
{
@ -278,9 +314,9 @@ void GuiWindow::MoveSelectionHor(int dir)
if(_elements.at(i)->GetLeft()*dir > left*dir && _elements.at(i)->GetTop() == top)
{
if(found == -1)
found = i;
found = int(i);
else if(_elements.at(i)->GetLeft()*dir < _elements.at(found)->GetLeft()*dir)
found = i; // this is a better match
found = int(i); // this is a better match
}
}
}
@ -290,7 +326,7 @@ void GuiWindow::MoveSelectionHor(int dir)
goto matchfound;
// match still not found, let's try the first button in the next row
for (i = 0; i < _elements.size(); i++)
for (i = 0; i < elemSize; ++i)
{
try
{
@ -327,7 +363,6 @@ void GuiWindow::MoveSelectionVert(int dir)
int found = -1;
u16 left = 0;
u16 top = 0;
u8 i = 0;
int selected = this->GetSelected();
@ -338,7 +373,8 @@ void GuiWindow::MoveSelectionVert(int dir)
}
// look for a button above/below, with the least horizontal difference
for (i = 0; i < _elements.size(); i++)
u32 elemSize = _elements.size();
for (u32 i = 0; i < elemSize; ++i)
{
try
{
@ -373,12 +409,23 @@ void GuiWindow::MoveSelectionVert(int dir)
}
}
void GuiWindow::ResetText()
{
u32 elemSize = _elements.size();
for (u32 i = 0; i < elemSize; i++)
{
try { _elements.at(i)->ResetText(); }
catch (const std::exception& e) { }
}
}
void GuiWindow::Update(GuiTrigger * t)
{
if(_elements.size() == 0 || (state == STATE_DISABLED && parentElement))
return;
for (u8 i = 0; i < _elements.size(); i++)
u32 elemSize = _elements.size();
for (u32 i = 0; i < elemSize; ++i)
{
try { _elements.at(i)->Update(t); }
catch (const std::exception& e) { }

View File

@ -1,6 +1,6 @@
/****************************************************************************
* DOSBox Wii Home Menu
* Tantric 2009
* Tantric 2009-2010
*
* menu.cpp
*
@ -20,7 +20,7 @@
#include "wiihardware.h"
#define THREAD_SLEEP 100
#define APPVERSION "1.2"
#define APPVERSION "1.3"
static GuiImageData * pointer[4];
static GuiWindow * mainWindow = NULL;
@ -70,7 +70,7 @@ static void * UpdateGUI (void *arg)
if(ExitRequested)
{
for(i = 0; i < 255; i += 15)
for(i = 0; i <= 255; i += 15)
{
mainWindow->Draw();
Menu_DrawRectangle(0,0,screenwidth,screenheight,(GXColor){0, 0, 0, i},1);

View File

@ -1,39 +1,44 @@
/*
Copyright (c) 2008 Francisco Muñoz 'Hermes' <www.elotrolado.net>
All rights reserved.
Proper (standard) vorbis usage by Tantric, 2009
Threading modifications/corrections by Tantric, 2009
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
- The names of the contributors may not be used to endorse or promote products derived
from this software without specific prior written permission.
- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
- The names of the contributors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NO_SOUND
#include "oggplayer.h"
#include <asndlib.h>
#include <tremor/ivorbiscodec.h>
#include <tremor/ivorbisfile.h>
#include <gccore.h>
#include <unistd.h>
#include <string.h>
#include "oggplayer.h"
/* functions to read the Ogg file from memory */
static struct
@ -46,14 +51,13 @@ static struct
static int f_read(void * punt, int bytes, int blocks, int *f)
{
int b;
int c;
int c = 0;
int d;
if (bytes * blocks <= 0)
return 0;
blocks = bytes * blocks;
c = 0;
blocks *= bytes;
while (blocks > 0)
{
@ -61,9 +65,9 @@ static int f_read(void * punt, int bytes, int blocks, int *f)
if (b > 4096)
b = 4096;
if (*f >= 0x666 && *f <= 0x669)
d = (*f) - 0x666;
if((unsigned)(d) <= (0x669 - 0x666))
{
d = (*f) - 0x666;
if (file[d].size == 0)
return -1;
if ((file[d].pos + b) > file[d].size)
@ -91,11 +95,12 @@ static int f_seek(int *f, ogg_int64_t offset, int mode)
{
if(f==NULL) return(-1);
int k, d;
int k;
mode &= 3;
if (*f >= 0x666 && *f <= 0x669)
int d = (*f) - 0x666;
if((unsigned)(d) <= (0x669 - 0x666))
{
d = (*f) - 0x666;
k = 0;
if (file[d].size == 0)
@ -116,7 +121,7 @@ static int f_seek(int *f, ogg_int64_t offset, int mode)
else
file[d].pos = offset;
}
if (mode == 1)
else if (mode == 1)
{
if ((file[d].pos + offset) >= file[d].size)
{
@ -131,7 +136,7 @@ static int f_seek(int *f, ogg_int64_t offset, int mode)
else
file[d].pos += offset;
}
if (mode == 2)
else if (mode == 2)
{
if ((file[d].size + offset) >= file[d].size)
@ -161,10 +166,9 @@ static int f_seek(int *f, ogg_int64_t offset, int mode)
static int f_close(int *f)
{
int d;
if (*f >= 0x666 && *f <= 0x669)
int d = (*f) - 0x666;
if((unsigned)(d) <= (0x669 - 0x666))
{
d = (*f) - 0x666;
file[d].size = 0;
file[d].pos = 0;
if (file[d].mem)
@ -180,11 +184,11 @@ static int f_close(int *f)
static long f_tell(int *f)
{
int k, d;
int k;
if (*f >= 0x666 && *f <= 0x669)
int d = (*f) - 0x666;
if((unsigned)(d) <= (0x669 - 0x666))
{
d = (*f) - 0x666;
k = file[d].pos;
}
else
@ -200,8 +204,15 @@ static int mem_open(char * ogg, int size)
if (one)
{
one = 0;
for (n = 0; n < 4; n++)
file[n].size = 0;
file[0].size = 0;
file[1].size = 0;
file[2].size = 0;
file[3].size = 0;
file[0].mem = ogg;
file[0].size = size;
file[0].pos = 0;
return (0x666);
}
for (n = 0; n < 4; n++)
@ -219,7 +230,7 @@ static int mem_open(char * ogg, int size)
static int mem_close(int fd)
{
if (fd >= 0x666 && fd <= 0x669) // it is a memory file descriptor?
if((unsigned)((fd) - 0x666) <= (0x669 - 0x666)) // it is a memory file descriptor?
{
fd -= 0x666;
file[fd].size = 0;
@ -348,8 +359,7 @@ static void * ogg_player_thread(private_data_ogg * priv)
priv[0].seek_time = -1;
}
ret
= ov_read(
ret = ov_read(
&priv[0].vf,
(void *) &priv[0].pcmout[priv[0].pcmout_pos][priv[0].pcm_indx],
MAX_PCMOUT,/*0,2,1,*/&priv[0].current_section);
@ -440,11 +450,11 @@ void StopOgg()
}
}
int PlayOgg(char * buf, int buflen, int time_pos, int mode)
int PlayOgg(const void *buffer, s32 len, int time_pos, int mode)
{
StopOgg();
private_ogg.fd = mem_open(buf, buflen);
private_ogg.fd = mem_open((char *)buffer, len);
if (private_ogg.fd < 0)
{
@ -508,8 +518,7 @@ int StatusOgg()
return 255; // EOF
else if (private_ogg.flag & 128)
return 2; // paused
else
return 1; // running
return 1; // running
}
void SetVolumeOgg(int volume)
@ -522,10 +531,8 @@ s32 GetTimeOgg()
{
int ret;
if (ogg_thread_running == 0 || private_ogg.fd < 0)
return 0;
return -1;
ret = ((s32) ov_time_tell(&private_ogg.vf));
if (ret < 0)
ret = 0;
return ret;
}

View File

@ -5,37 +5,32 @@
Proper (standard) vorbis usage by Tantric, 2009
Threading modifications/corrections by Tantric, 2009
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
- The names of the contributors may not be used to endorse or promote products derived
from this software without specific prior written permission.
- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
- The names of the contributors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NO_SOUND
#ifndef __OGGPLAYER_H__
#define __OGGPLAYER_H__
#include <asndlib.h>
#include <tremor/ivorbiscodec.h>
#include <tremor/ivorbisfile.h>
#ifdef __cplusplus
extern "C"
{
@ -49,129 +44,69 @@ extern "C"
#define OGG_STATUS_PAUSED 2
#define OGG_STATUS_EOF 255
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* Player OGG functions */
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* int PlayOgg(int fd, int time_pos, int mode);
Play an Ogg file. This file can be loaded from memory (mem_open(void *ogg, int size_ogg)) or from device with open("device:file.ogg",O_RDONLY,0);
NOTE: The file is closed by the player when you call PlayOgg(), StopOgg() or if it fail.
-- Params ---
fd: file descriptor from open() or mem_open()
time_pos: initial time position in the file (in milliseconds). For example, use 30000 to advance 30 seconds
mode: Use OGG_ONE_TIME or OGG_INFINITE_TIME. When you use OGG_ONE_TIME the sound stops and StatusOgg() return OGG_STATUS_EOF
return: 0- Ok, -1 Error
*/
int PlayOgg(char * buf, int buflen, int time_pos, int mode);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* void StopOgg();
Stop an Ogg file.
NOTE: The file is closed and the player thread is released
-- Params ---
*/
/****************************************************************************
* PlayOgg
*
* Creates a thread that starts playing from the specific Ogg buffer
* buffer - pointer to the start of the Ogg data
* len - length of Ogg file
* time_pos - initial time position at which to start playback
* mode - playback mode (OGG_ONE_TIME or OGG_INFINITE_TIME)
* returns: -1 on error, 0 on success
***************************************************************************/
int PlayOgg(const void *buffer, s32 len, int time_pos, int mode);
/****************************************************************************
* StopOgg
*
* Stops playback. The player thread is shut down.
***************************************************************************/
void StopOgg();
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* void PauseOgg(int pause);
Pause an Ogg file.
-- Params ---
pause: 0 -> continue, 1-> pause
*/
/****************************************************************************
* PauseOgg
*
* Pauses playback. 0 -> continue, 1-> pause
***************************************************************************/
void PauseOgg(int pause);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* int StatusOgg();
Return the Ogg status
-- Params ---
return: OGG_STATUS_RUNNING
OGG_STATUS_ERR -> not initialized?
OGG_STATUS_PAUSED
OGG_STATUS_EOF -> player stopped by End Of File
*/
/****************************************************************************
* StatusOgg
*
* Returns the Ogg player's status
* returns:
* OGG_STATUS_RUNNING
* OGG_STATUS_ERR -> not initialized
* OGG_STATUS_PAUSED
* OGG_STATUS_EOF -> player stopped by End Of File
***************************************************************************/
int StatusOgg();
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* void SetVolumeOgg(int volume);
Set the Ogg playing volume.
NOTE: it change the volume of voice 0 (used for the Ogg player)
-- Params ---
volume: 0 to 255 (max)
*/
/****************************************************************************
* SetVolumeOgg
*
* Sets the Ogg playback volume (0 to 255 (max))
***************************************************************************/
void SetVolumeOgg(int volume);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* s32 GetTimeOgg();
Return the Ogg time from the starts of the file
-- Params ---
return: 0 -> Ok or error condition (you must ignore this value)
>0 -> time in milliseconds from the starts
*/
/****************************************************************************
* GetTimeOgg
*
* Gets current Ogg position
* returns -1 on error, or the time in milliseconds from the start
***************************************************************************/
s32 GetTimeOgg();
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* void SetTimeOgg(s32 time_pos);
Set the time position
NOTE: The file is closed by the player when you call PlayOgg(), StopOgg() or if it fail.
-- Params ---
time_pos: time position in the file (in milliseconds). For example, use 30000 to advance 30 seconds
*/
/****************************************************************************
* SetTimeOgg
*
* Sets the time position
* time_pos: time position (in milliseconds) to advance
***************************************************************************/
void SetTimeOgg(s32 time_pos);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
#ifdef __cplusplus
}
#endif
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +1,15 @@
/********************************************************************************************
PNGU Version : 0.2a
Coder : frontier
More info : http://frontier-dev.net
Modified by Tantric, 2009
*
* PNGU
*
* Original author: frontier (http://frontier-dev.net)
* Modified by Tantric, 2009-2010
*
********************************************************************************************/
#ifndef __PNGU__
#define __PNGU__
// Return codes
#define PNGU_OK 0
#define PNGU_ODD_WIDTH 1
#define PNGU_ODD_STRIDE 2
#define PNGU_INVALID_WIDTH_OR_HEIGHT 3
#define PNGU_FILE_IS_NOT_PNG 4
#define PNGU_UNSUPPORTED_COLOR_TYPE 5
#define PNGU_NO_FILE_SELECTED 6
#define PNGU_CANT_OPEN_FILE 7
#define PNGU_CANT_READ_FILE 8
#define PNGU_LIB_ERROR 9
// Color types
#define PNGU_COLOR_TYPE_GRAY 1
#define PNGU_COLOR_TYPE_GRAY_ALPHA 2
#define PNGU_COLOR_TYPE_PALETTE 3
#define PNGU_COLOR_TYPE_RGB 4
#define PNGU_COLOR_TYPE_RGB_ALPHA 5
#define PNGU_COLOR_TYPE_UNKNOWN 6
#ifdef __cplusplus
extern "C" {
#endif
@ -66,28 +43,8 @@ typedef struct
struct _IMGCTX;
typedef struct _IMGCTX *IMGCTX;
/****************************************************************************
* Pixel conversion *
****************************************************************************/
// Macro to convert RGB8 values to RGB565
#define PNGU_RGB8_TO_RGB565(r,g,b) ( ((((PNGU_u16) r) & 0xF8U) << 8) | ((((PNGU_u16) g) & 0xFCU) << 3) | (((PNGU_u16) b) >> 3) )
// Macro to convert RGBA8 values to RGB5A3
#define PNGU_RGB8_TO_RGB5A3(r,g,b,a) (PNGU_u16) (((a & 0xE0U) == 0xE0U) ? \
(0x8000U | ((((PNGU_u16) r) & 0xF8U) << 7) | ((((PNGU_u16) g) & 0xF8U) << 2) | (((PNGU_u16) b) >> 3)) : \
(((((PNGU_u16) a) & 0xE0U) << 7) | ((((PNGU_u16) r) & 0xF0U) << 4) | (((PNGU_u16) g) & 0xF0U) | ((((PNGU_u16) b) & 0xF0U) >> 4)))
// Function to convert two RGB8 values to YCbYCr
PNGU_u32 PNGU_RGB8_TO_YCbYCr (PNGU_u8 r1, PNGU_u8 g1, PNGU_u8 b1, PNGU_u8 r2, PNGU_u8 g2, PNGU_u8 b2);
// Function to convert an YCbYCr to two RGB8 values.
void PNGU_YCbYCr_TO_RGB8 (PNGU_u32 ycbycr, PNGU_u8 *r1, PNGU_u8 *g1, PNGU_u8 *b1, PNGU_u8 *r2, PNGU_u8 *g2, PNGU_u8 *b2);
/****************************************************************************
* Image context handling *
* Image context handling *
****************************************************************************/
// Selects a PNG file, previosly loaded into a buffer, and creates an image context for subsequent procesing.
@ -99,78 +56,23 @@ IMGCTX PNGU_SelectImageFromDevice (const char *filename);
// Frees resources associated with an image context. Always call this function when you no longer need the IMGCTX.
void PNGU_ReleaseImageContext (IMGCTX ctx);
/****************************************************************************
* Miscelaneous *
* Miscellaneous *
****************************************************************************/
// Retrieves info from selected PNG file, including image dimensions, color format, background and transparency colors.
int PNGU_GetImageProperties (IMGCTX ctx, PNGUPROP *fileproperties);
/****************************************************************************
* Image conversion *
* Image conversion *
****************************************************************************/
// Expands selected image into an YCbYCr buffer. You need to specify context, image dimensions,
// destination address and stride in pixels (stride = buffer width - image width).
int PNGU_DecodeToYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride);
// Macro for decoding an image inside a buffer at given coordinates.
#define PNGU_DECODE_TO_COORDS_YCbYCr(ctx,coordX,coordY,imgWidth,imgHeight,bufferWidth,bufferHeight,buffer) \
\
PNGU_DecodeToYCbYCr (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \
(coordX) * 2, (bufferWidth) - (imgWidth))
// Expands selected image into a linear RGB565 buffer. You need to specify context, image dimensions,
// destination address and stride in pixels (stride = buffer width - image width).
int PNGU_DecodeToRGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride);
// Macro for decoding an image inside a buffer at given coordinates.
#define PNGU_DECODE_TO_COORDS_RGB565(ctx,coordX,coordY,imgWidth,imgHeight,bufferWidth,bufferHeight,buffer) \
\
PNGU_DecodeToRGB565 (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \
(coordX) * 2, (bufferWidth) - (imgWidth))
// Expands selected image into a linear RGBA8 buffer. You need to specify context, image dimensions,
// destination address, stride in pixels and default alpha value, which is used if the source image
// doesn't have an alpha channel.
int PNGU_DecodeToRGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride, PNGU_u8 default_alpha);
// Macro for decoding an image inside a buffer at given coordinates.
#define PNGU_DECODE_TO_COORDS_RGBA8(ctx,coordX,coordY,imgWidth,imgHeight,default_alpha,bufferWidth,bufferHeight,buffer) \
\
PNGU_DecodeToRGBA8 (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \
(coordX) * 2, (bufferWidth) - (imgWidth), default_alpha)
// Expands selected image into a 4x4 tiled RGB565 buffer. You need to specify context, image dimensions
// and destination address.
int PNGU_DecodeTo4x4RGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer);
// Expands selected image into a 4x4 tiled RGB5A3 buffer. You need to specify context, image dimensions,
// destination address and default alpha value, which is used if the source image doesn't have an alpha channel.
int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha);
// Expands selected image into a 4x4 tiled RGBA8 buffer. You need to specify context, image dimensions,
// destination address and default alpha value, which is used if the source image doesn't have an alpha channel.
int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha);
// Encodes an YCbYCr image in PNG format and stores it in the selected device or memory buffer. You need to
// specify context, image dimensions, destination address and stride in pixels (stride = buffer width - image width).
int PNGU_EncodeFromYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride);
PNGU_u8 * DecodePNG(const PNGU_u8 *src, int *width, int *height, int maxwidth, int maxheight);
int PNGU_EncodeFromRGB (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride);
int PNGU_EncodeFromGXTexture (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride);
// Macro for encoding an image stored into an YCbYCr buffer at given coordinates.
#define PNGU_ENCODE_TO_COORDS_YCbYCr(ctx,coordX,coordY,imgWidth,imgHeight,bufferWidth,bufferHeight,buffer) \
\
PNGU_EncodeFromYCbYCr (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \
(coordX) * 2, (bufferWidth) - (imgWidth))
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,6 +1,6 @@
/****************************************************************************
* DOSBox Wii
* Tantric 2009
* Tantric 2009-2010
***************************************************************************/
#include <gccore.h>
@ -111,14 +111,19 @@ static void * PressKeys (void *arg)
MAPPER_CheckEvent(&event);
usleep(600);
}
// hack to allow mappings of SDL keys > 127
int keyoffset = 0;
if(dosboxCommand[i] >= 14 && dosboxCommand[i] <= 25)
keyoffset = 268; // F1-F12 (282-293)
event.type = SDL_KEYDOWN;
event.key.keysym.sym = (SDLKey)dosboxCommand[i];
event.key.keysym.sym = (SDLKey)((int)dosboxCommand[i]+keyoffset);
MAPPER_CheckEvent(&event);
usleep(600);
event.type = SDL_KEYUP;
event.key.keysym.sym = (SDLKey)dosboxCommand[i];
event.key.keysym.sym = (SDLKey)((int)dosboxCommand[i]+keyoffset);
MAPPER_CheckEvent(&event);
usleep(600);
@ -130,17 +135,6 @@ static void * PressKeys (void *arg)
usleep(600);
}
}
event.type = SDL_KEYDOWN;
event.key.keysym.sym = SDLK_RETURN;
MAPPER_CheckEvent(&event);
usleep(600);
event.type = SDL_KEYUP;
event.key.keysym.sym = SDLK_RETURN;
MAPPER_CheckEvent(&event);
usleep(600);
dosboxCommand[0] = 0;
}
return NULL;

View File

@ -1,6 +1,6 @@
/****************************************************************************
* DOSBox Wii
* Tantric 2009
* Tantric 2009-2010
***************************************************************************/
#ifndef WIIHARDWARE_H

View File

@ -1,6 +1,6 @@
/****************************************************************************
* DOSBox Wii Home Menu
* Tantric 2009
* Tantric 2009-2010
*
* video.cpp
*

View File

@ -1,6 +1,6 @@
/****************************************************************************
* DOSBox Wii Home Menu
* Tantric 2009
* Tantric 2009-2010
*
* wiivideo.h
*

View File

@ -305,6 +305,7 @@ void DOS_Shell::Run(void) {
WriteOut(MSG_Get("SHELL_STARTUP_DEBUG"));
#endif
if (machine == MCH_CGA) WriteOut(MSG_Get("SHELL_STARTUP_CGA"));
if (machine == MCH_HERC) WriteOut(MSG_Get("SHELL_STARTUP_HERC"));
WriteOut(MSG_Get("SHELL_STARTUP_END"));
if (cmd->FindString("/INIT",line,true)) {
@ -503,7 +504,7 @@ void SHELL_Init() {
"| For a short introduction for new users type: \033[33mINTRO\033[37m |\n"
"| For supported shell commands type: \033[33mHELP\033[37m |\n"
"| |\n"
"| If you want more speed, try \033[31mctrl-F8\033[37m and \033[31mctrl-F12\033[37m. |\n"
"| To adjust the emulated CPU speed, use \033[31mctrl-F11\033[37m and \033[31mctrl-F12\033[37m. |\n"
"| To activate the keymapper \033[31mctrl-F1\033[37m. |\n"
"| For more information read the \033[36mREADME\033[37m file in the DOSBox directory. |\n"
"| |\n"
@ -512,6 +513,9 @@ void SHELL_Init() {
"| Use \033[31m(alt-)F11\033[37m to change the colours when in this mode. |\n"
"| |\n"
);
MSG_Add("SHELL_STARTUP_HERC","\xBA Use \033[31mF11\033[37m to cycle through white, amber, and green monochrome color. \xBA\n"
"\xBA \xBA\n"
);
MSG_Add("SHELL_STARTUP_DEBUG",
"| Press \033[31malt-Pause\033[37m to enter the debugger or start the exe with \033[33mDEBUG\033[37m. |\n"
"| |\n"
@ -535,7 +539,7 @@ void SHELL_Init() {
"\xBA For a short introduction for new users type: \033[33mINTRO\033[37m \xBA\n"
"\xBA For supported shell commands type: \033[33mHELP\033[37m \xBA\n"
"\xBA \xBA\n"
"\xBA If you want more speed, try \033[31mctrl-F8\033[37m and \033[31mctrl-F12\033[37m. \xBA\n"
"\xBA To adjust the emulated CPU speed, use \033[31mctrl-F11\033[37m and \033[31mctrl-F12\033[37m. \xBA\n"
"\xBA To activate the keymapper \033[31mctrl-F1\033[37m. \xBA\n"
"\xBA For more information read the \033[36mREADME\033[37m file in the DOSBox directory. \xBA\n"
"\xBA \xBA\n"
@ -544,6 +548,9 @@ void SHELL_Init() {
"\xBA Use \033[31m(alt-)F11\033[37m to change the colours when in this mode. \xBA\n"
"\xBA \xBA\n"
);
MSG_Add("SHELL_STARTUP_HERC","\xBA Use \033[31mF11\033[37m to cycle through white, amber, and green monochrome color. \xBA\n"
"\xBA \xBA\n"
);
MSG_Add("SHELL_STARTUP_DEBUG",
"\xBA Press \033[31malt-Pause\033[37m to enter the debugger or start the exe with \033[33mDEBUG\033[37m. \xBA\n"
"\xBA \xBA\n"

View File

@ -7,8 +7,8 @@ dosbox_ico ICON "dosbox.ico"
// version resource
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,73,0,0
PRODUCTVERSION 0,73,0,0
FILEVERSION 0,74,0,0
PRODUCTVERSION 0,74,0,0
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x0L
FILEOS 0x40004L
@ -19,15 +19,15 @@ BEGIN
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "© 2002-2009 DOSBox Team, published under GNU GPL"
VALUE "Comments", "© 2002-2010 DOSBox Team, published under GNU GPL"
VALUE "CompanyName", "DOSBox Team"
VALUE "FileDescription", "DOSBox DOS Emulator"
VALUE "FileVersion", "0, 73, 0, 0"
VALUE "FileVersion", "0, 74, 0, 0"
VALUE "InternalName", "DOSBox"
VALUE "LegalCopyright", "Copyright © 2002-2009 DOSBox Team"
VALUE "LegalCopyright", "Copyright © 2002-2010 DOSBox Team"
VALUE "OriginalFilename", "dosbox.exe"
VALUE "ProductName", "DOSBox DOS Emulator"
VALUE "ProductVersion", "0, 73, 0, 0"
VALUE "ProductVersion", "0, 74, 0, 0"
END
END
BLOCK "VarFileInfo"