remove unused/unmaintained code

RIP Symbian..
mz80 is unused
This commit is contained in:
notaz 2013-06-22 19:16:16 +03:00
parent 1b85bf1c23
commit fb7a7fea87
112 changed files with 0 additions and 45924 deletions

View file

@ -1,13 +0,0 @@
CFLAGS = -Wno-conversion -Wno-sign-compare # -Wno-pointer-sign
all : mz80.asm
mz80.asm : makez80
./makez80 -s -l -x86 $@
makez80 : makez80.o
clean :
$(RM) makez80 makez80.o mz80.asm

View file

@ -1,18 +0,0 @@
all : mz80.obj
mz80.obj : mz80.asm
nasm -f win32 mz80.asm -o $@
mz80.asm : makez80.exe
makez80.exe -s -x86 $@
makez80.exe : makez80.c
cl /DWIN32 /W3 makez80.c
clean : tidy
del mz80.obj
tidy :
del mz80.asm makez80.exe makez80.obj

View file

@ -1,13 +0,0 @@
/* compiler dependence */
#ifndef UINT8
typedef unsigned char UINT8; /* unsigned 8bit */
typedef unsigned short UINT16; /* unsigned 16bit */
typedef unsigned int UINT32; /* unsigned 32bit */
#endif
#ifndef INT8
typedef signed char INT8; /* signed 8bit */
typedef signed short INT16; /* signed 16bit */
typedef signed int INT32; /* signed 32bit */
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,394 +0,0 @@
/* Multi-Z80 32 Bit emulator */
/* Copyright 1996, Neil Bradley, All rights reserved
*
* License agreement:
*
* The mZ80 emulator may be distributed in unmodified form to any medium.
*
* mZ80 May not be sold, or sold as a part of a commercial package without
* the express written permission of Neil Bradley (neil@synthcom.com). This
* includes shareware.
*
* Modified versions of mZ80 may not be publicly redistributed without author
* approval (neil@synthcom.com). This includes distributing via a publicly
* accessible LAN. You may make your own source modifications and distribute
* mZ80 in object only form.
*
* mZ80 Licensing for commercial applications is available. Please email
* neil@synthcom.com for details.
*
* Synthcom Systems, Inc, and Neil Bradley will not be held responsible for
* any damage done by the use of mZ80. It is purely "as-is".
*
* If you use mZ80 in a freeware application, credit in the following text:
*
* "Multi-Z80 CPU emulator by Neil Bradley (neil@synthcom.com)"
*
* must accompany the freeware application within the application itself or
* in the documentation.
*
* Legal stuff aside:
*
* If you find problems with mZ80, please email the author so they can get
* resolved. If you find a bug and fix it, please also email the author so
* that those bug fixes can be propogated to the installed base of mZ80
* users. If you find performance improvements or problems with mZ80, please
* email the author with your changes/suggestions and they will be rolled in
* with subsequent releases of mZ80.
*
* The whole idea of this emulator is to have the fastest available 32 bit
* Multi-z80 emulator for the PC, giving maximum performance.
*/
/* General z80 based defines */
#ifndef _MZ80_H_
#define _MZ80_H_
#ifndef UINT32
#define UINT32 unsigned long int
#endif
#ifndef UINT16
#define UINT16 unsigned short int
#endif
#ifndef UINT8
#define UINT8 unsigned char
#endif
#ifndef INT32
#define INT32 signed long int
#endif
#ifndef INT16
#define INT16 signed short int
#endif
#ifndef INT8
#define INT8 signed char
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _MEMORYREADWRITEBYTE_
#define _MEMORYREADWRITEBYTE_
struct MemoryWriteByte
{
UINT32 lowAddr;
UINT32 highAddr;
void (*memoryCall)(UINT32, UINT8, struct MemoryWriteByte *);
void *pUserArea;
};
struct MemoryReadByte
{
UINT32 lowAddr;
UINT32 highAddr;
UINT8 (*memoryCall)(UINT32, struct MemoryReadByte *);
void *pUserArea;
};
#endif // _MEMORYREADWRITEBYTE_
struct z80PortWrite
{
UINT16 lowIoAddr;
UINT16 highIoAddr;
void (*IOCall)(UINT16, UINT8, struct z80PortWrite *);
void *pUserArea;
};
struct z80PortRead
{
UINT16 lowIoAddr;
UINT16 highIoAddr;
UINT16 (*IOCall)(UINT16, struct z80PortRead *);
void *pUserArea;
};
struct z80TrapRec
{
UINT16 trapAddr;
UINT8 skipCnt;
UINT8 origIns;
};
typedef union
{
UINT32 af;
struct
{
#ifdef WORDS_BIGENDIAN
UINT16 wFiller;
UINT8 a;
UINT8 f;
#else
UINT8 f;
UINT8 a;
UINT16 wFiller;
#endif
} half;
} reg_af;
#define z80AF z80af.af
#define z80A z80af.half.a
#define z80F z80af.half.f
typedef union
{
UINT32 bc;
struct
{
#ifdef WORDS_BIGENDIAN
UINT16 wFiller;
UINT8 b;
UINT8 c;
#else
UINT8 c;
UINT8 b;
UINT16 wFiller;
#endif
} half;
} reg_bc;
#define z80BC z80bc.bc
#define z80B z80bc.half.b
#define z80C z80bc.half.c
typedef union
{
UINT32 de;
struct
{
#ifdef WORDS_BIGENDIAN
UINT16 wFiller;
UINT8 d;
UINT8 e;
#else
UINT8 e;
UINT8 d;
UINT16 wFiller;
#endif
} half;
} reg_de;
#define z80DE z80de.de
#define z80D z80de.half.d
#define z80E z80de.half.e
typedef union
{
UINT32 hl;
struct
{
#ifdef WORDS_BIGENDIAN
UINT16 wFiller;
UINT8 h;
UINT8 l;
#else
UINT8 l;
UINT8 h;
UINT16 wFiller;
#endif
} half;
} reg_hl;
#define z80HL z80hl.hl
#define z80H z80hl.half.h
#define z80L z80hl.half.l
#define z80SP z80sp.sp
typedef union
{
UINT32 ix;
struct
{
#ifdef WORDS_BIGENDIAN
UINT16 wFiller;
UINT8 xh;
UINT8 xl;
#else
UINT8 xl;
UINT8 xh;
UINT16 wFiller;
#endif
} half;
} reg_ix;
#define z80IX z80ix.ix
#define z80XH z80ix.half.xh
#define z80XL z80ix.half.xl
typedef union
{
UINT32 iy;
struct
{
#ifdef WORDS_BIGENDIAN
UINT16 wFiller;
UINT8 yh;
UINT8 yl;
#else
UINT8 yl;
UINT8 yh;
UINT16 wFiller;
#endif
} half;
} reg_iy;
#define z80IY z80iy.iy
#define z80YH z80iy.half.yh
#define z80YL z80iy.half.yl
struct mz80context
{
UINT8 *z80Base;
struct MemoryReadByte *z80MemRead;
struct MemoryWriteByte *z80MemWrite;
struct z80PortRead *z80IoRead;
struct z80PortWrite *z80IoWrite;
UINT32 z80clockticks;
UINT32 z80iff;
UINT32 z80interruptMode;
UINT32 z80halted;
reg_af z80af;
reg_bc z80bc;
reg_de z80de;
reg_hl z80hl;
UINT32 z80afprime;
UINT32 z80bcprime;
UINT32 z80deprime;
UINT32 z80hlprime;
reg_ix z80ix;
reg_iy z80iy;
UINT32 z80sp;
UINT32 z80pc;
UINT32 z80nmiAddr;
UINT32 z80intAddr;
UINT32 z80rCounter;
UINT8 z80i;
UINT8 z80r;
UINT8 z80intPending;
};
// These are the enumerations used for register access. DO NOT ALTER THEIR
// ORDER! It must match the same order as in the mz80.c/mz80.asm files!
enum
{
#ifndef CPUREG_PC
CPUREG_PC = 0,
#endif
CPUREG_Z80_AF = 1,
CPUREG_Z80_BC,
CPUREG_Z80_DE,
CPUREG_Z80_HL,
CPUREG_Z80_AFPRIME,
CPUREG_Z80_BCPRIME,
CPUREG_Z80_DEPRIME,
CPUREG_Z80_HLPRIME,
CPUREG_Z80_IX,
CPUREG_Z80_IY,
CPUREG_Z80_SP,
CPUREG_Z80_I,
CPUREG_Z80_R,
CPUREG_Z80_A,
CPUREG_Z80_B,
CPUREG_Z80_C,
CPUREG_Z80_D,
CPUREG_Z80_E,
CPUREG_Z80_H,
CPUREG_Z80_L,
CPUREG_Z80_F,
CPUREG_Z80_CARRY,
CPUREG_Z80_NEGATIVE,
CPUREG_Z80_PARITY,
CPUREG_Z80_OVERFLOW,
CPUREG_Z80_HALFCARRY,
CPUREG_Z80_ZERO,
CPUREG_Z80_SIGN,
CPUREG_Z80_IFF1,
CPUREG_Z80_IFF2,
// Leave this here!
CPUREG_Z80_MAX_INDEX
};
extern UINT32 mz80exec(UINT32);
extern UINT32 mz80GetContextSize(void);
extern UINT32 mz80GetElapsedTicks(UINT32);
extern void mz80ReleaseTimeslice(void);
extern void mz80GetContext(void *);
extern void mz80SetContext(void *);
extern void mz80reset(void);
extern void mz80ClearPendingInterrupt(void);
extern UINT32 mz80int(UINT32);
extern UINT32 mz80nmi(void);
extern void mz80init(void);
extern void mz80shutdown(void);
extern UINT32 z80intAddr;
extern UINT32 z80nmiAddr;
// Debugger useful routines
extern UINT8 mz80SetRegisterValue(void *, UINT32, UINT32);
extern UINT32 mz80GetRegisterValue(void *, UINT32);
extern UINT32 mz80GetRegisterTextValue(void *, UINT32, UINT8 *);
extern UINT8 *mz80GetRegisterName(UINT32);
// Memory/IO read/write commands
#ifndef VALUE_BYTE
#define VALUE_BYTE 0
#endif
#ifndef VALUE_WORD
#define VALUE_WORD 1
#endif
#ifndef VALUE_DWORD
#define VALUE_DWORD 2
#endif
#ifndef VALUE_IO
#define VALUE_IO 3
#endif
extern void mz80WriteValue(UINT8 bWhat, UINT32 dwAddr, UINT32 dwData);
extern UINT32 mz80ReadValue(UINT8 bWhat, UINT32 dwAddr);
// Flag definitions
#define Z80_FLAG_CARRY 0x01
#define Z80_FLAG_NEGATIVE 0x02
#define Z80_FLAG_OVERFLOW_PARITY 0x04
#define Z80_FLAG_UNDEFINED1 0x08
#define Z80_FLAG_HALF_CARRY 0x10
#define Z80_FLAG_UNDEFINED2 0x20
#define Z80_FLAG_ZERO 0x40
#define Z80_FLAG_SIGN 0x80
#define IFF1 0x01
#define IFF2 0x02
typedef struct mz80context CONTEXTMZ80;
#ifdef __cplusplus
};
#endif
#endif // _MZ80_H_

View file

@ -1,809 +0,0 @@
Multi-Z80 32 Bit emulator
Copyright 1996, 1997, 1998, 1999, 2000 - Neil Bradley, All rights reserved
MZ80 License agreement
-----------------------
(MZ80 Refers to both the assembly code emitted by makez80.c and makez80.c
itself)
MZ80 May be distributed in unmodified form to any medium.
MZ80 May not be sold, or sold as a part of a commercial package without
the express written permission of Neil Bradley (neil@synthcom.com). This
includes shareware.
Modified versions of MZ80 may not be publicly redistributed without author
approval (neil@synthcom.com). This includes distributing via a publicly
accessible LAN. You may make your own source modifications and distribute
MZ80 in source or object form, but if you make modifications to MZ80
then it should be noted in the top as a comment in makez80.c.
MZ80 Licensing for commercial applications is available. Please email
neil@synthcom.com for details.
Synthcom Systems, Inc, and Neil Bradley will not be held responsible for
any damage done by the use of MZ80. It is purely "as-is".
If you use MZ80 in a freeware application, credit in the following text:
"Multi-Z80 CPU emulator by Neil Bradley (neil@synthcom.com)"
must accompany the freeware application within the application itself or
in the documentation.
Legal stuff aside:
If you find problems with MZ80, please email the author so they can get
resolved. If you find a bug and fix it, please also email the author so
that those bug fixes can be propogated to the installed base of MZ80
users. If you find performance improvements or problems with MZ80, please
email the author with your changes/suggestions and they will be rolled in
with subsequent releases of MZ80.
The whole idea of this emulator is to have the fastest available 32 bit
Multi-Z80 emulator for the x86, giving maximum performance.
MZ80 Contact information
-------------------------
Author : Neil Bradley (neil@synthcom.com)
Distribution: ftp://ftp.synthcom.com/pub/emulators/cpu/makez80.zip (latest)
You can join the cpuemu mailing list on Synthcom for discussion of Neil
Bradley's Z80 (and other) CPU emulators. Send a message to
"cpuemu-request@synthcom.com" with "subscribe" in the message body. The
traffic is fairly low, and is used as a general discussion and announcement
for aforementioned emulators.
MZ80 Documentation
-------------------
MZ80 Is a full featured Z80 emulator coded in 32 bit assembly. It runs well
over a hundred games, in addition to it supporting many undocumented Z80
instructions required to run some of the Midway MCR games, Galaga, and
countless other wonderful Z80 based arcade games.
MZ80 Contains a makez80.c program that must be compiled. It is the program
that emits the assembly code that NASM will compile. This minimizes the
possibility of bugs creeping in to MZ80 for the different addressing modes
for each instruction. It requires NASM 0.97 or greater.
The goal of MZ80 is to have a high performance Z80 emulator that is capable
of running multiple emulations concurrently at full speed, even on lower-end
machines (486/33). MZ80 Harnesses the striking similarities of both the Z80
and the x86 instruction sets to take advantage of flag handling which greatly
reduces the time required to emulate a processor, so no extra time is spent
computing things that are already available in the native x86 processor,
allowing it to perform leaps and bounds over comparable C based Z80 emulators
on the same platform.
MZ80 Is designed exclusively for use with NASM, the Netwide Assembler. This
gives the ultimate in flexibility, as NASM can emit object files that work
with Watcom, Microsoft Visual C++ (4.0-current), DJGPP, Borland C++, and
gcc under FreeBSD or Linux. MZ80 Has been tested with each one of these
compilers and is known to work properly on each.
What's in the package
---------------------
MZ80.TXT - This text file
MAKEZ80.C - Multi Z80 32 Bit emulator emitter program
MZ80.H - C Header file for MZ80 functions
What's new in this release
--------------------------
Revision 3.4:
* Fixed the overflow flag not getting cleared in the SetOverflow()
routine. It caused strange problems with a handful of Genesis games
* Removed invalid instruction in the C version so that more
instructions will execute
Revision 3.3:
* Undocumented opcodes added to the C emitter
* Bug fix to the C emission that properly handles shared RAM regions
(I.E. with handlers that are NULL)
* Now using 32 bit registers to do register/memory access. Slight
speed increase (assembly version only)
Revision 3.2:
* R Register emulation now accurate with a real Z80
* mz80int() Called when interrupts are disabled causes the
z80intPending flag to be set, and an interrupt will be caused after
the execution of EI and the next instruction. See "IMPORTANT NOTE
ABOUT INTERRUPTS" below
* The instruction after EI executes fully before interrupt status is
checked. (as does a real Z80)
Revision 3.1:
* Fixed bug in memory dereference when handler was set to NULL (keeps
system from crashing or faulting)
* Removed the only stricmp() from the entire file and replaced it
with strcmp() so that stdlibs without it will compile
* Changed cyclesRemaining > 0 to cyclesRemaining >= 0 to be compatible
with the ASM core
* Removed additional sub [dwCyclesRemaining], 5 at the beginning of
mz80exec() (ASM Core only). Increases timing accuracy.
* NMIs And INTs add additional time to dwElapsedTicks as it should
* mz80ReleaseTimeslice() Sets remaining clocks to 0 instead of 1
Revision 3.0:
* All instructions validated against a real Z80. Used an ISA card
with a Z80 on it to validate flag handling, instruction handling,
timing, and other goodies. The only thing not implemented/emulated
is flag bit 3 & 5 emulation. Believed to be 100% bug free!
* 80% Speed improvement over version 2.7 of mz80
* z80stb.c Removed. Use -c to emit a C version of mz80! API compatible!
Note that this is mostly, but not fully, debugged, so consider the
C version a beta! It's at least healthier than z80stb.c was. The C
version does not include the undocumented Z80 instructions.
* mz80nmi() No longer trashes registers it uses when using -cs
* IN/OUT Instructions work properly when using -16
* IN A, (xxh) uses A as high 8 bits of I/O fetch address when using -16
* IM 0/IM 1 Description in documentation fixed
* Sizes of all context registers increased to 32 bits - for speed!
* IFF1/IFF2 Now properly emulated
* JR Instruction offset can fetch from $ffff and properly wrap
* LDIR/LDDR Instruction now won't go to completion - instead it will
run until BC=0 or the # of cycles to execute have expired. These
instructions used to run to completion - even beyond the # of cycles
left to execute
* INI/IND/INIR/INDR countdown bug fixed - it was decrementing B twice
for each IN! Whoops!
* If you specify NULL as a handler address to a memory region, mz80 will
use vpData as a pointer to where that block of data resides. Quite
useful for multiprocessor emulations that share the same memory.
* EDI Now keeps track of cycle counting for faster execution
* Modified memory region scanning code to use 32 bit registers instead
of their 16 bit counterparts
* Get/SetContext() uses rep movsd/movsb. Insignificant overall, but
why waste the time?
* Debugging routines added. See the "DEBUGGING" section below for more
information. NOTE: The debugging routines are not yet available in
the C emission.
* Timing done slightly differently now. Mz80 now executes one
instruction past the timing given on input. For example, mz80exec(0)
will cause a single instruction to be executed (thusly -ss was
removed).
Revision 2.7:
* Fixed OTIR/OTDR/INIR/INDR instructions so their 16 bit counterparts
work properly
* Emulation core 30-70% faster overall than 2.6 due to optimization to
the timing routines
* Replaced word reads/writes with a special word write routine rather
than the standard calling to read/write byte functions
* z80stb.c (the C equivalent of mz80) compiles properly now
* Fixed OS/2 text/segment issue
* Fixed bug in set/getCPU context that ensures that ES=DS and avoids
crashes. Caused crashes under OS/2 and other OS's
Revision 2.6:
* Emulator core 5-30% faster overall. Some 16 and 8 bit instructions
sped up when using their 32 bit equivalents.
* Fix to -l so that proper labels without leading and trailing
underscores so Linux/FreeBSD compiles will work properly
* Single step now executes the # of instructions passed in to z80exec()
instead of just 1 as it had in prior releases. This is only active
when the -ss option is used.
* The -nt option was added. This will cause the timing information to
not be added in, speeding up execution. Warning: Only do this if your
emulated target does not require instruction timing!
* Updated documentation errors
* C Version of mz80 (mz80.c) that is API compliant is distributed with
the archive (With kind permission of Edward Massey).
Revision 2.5:
* Fixed an unconditional flag being cleared in the ddcbxx instructions.
It caused Donkey Kong's barrels to not roll.
Revision 2.4:
* Fixed improper HALT handling (didn't advance the PTR when it should)
* Fixed SRL (IX+$xx) instruction so that carry wasn't trashed
* Fixed single stepping problems with it giving too much time to
any given instruction
* Fixed half carry flag handling with 16 bit SBC and ADD instructions
* Fixed DAA emulation so that parity flags weren't getting trashed
Revision 2.3:
* Fixed many stack handling bugs
* Timing problems fixed. The prior version was causing massive
overruns on maximum timeslices with some insutructions.
Revision 2.2:
* Fixed a bug in CPI/CPD/CPIR/CPDR that mishandled flags
* All known bugs are out of mz80 now
* Added the -cs option to route all stack operations through the
handlers (required for games like Galaga)
Revision 2.1:
* Fixed a bug in CPI/CPD/CPIR/CPDR that caused intermittent lockups.
Also fixed a bug that caused erratic behavior in several video games.
* Added INI/IND/INIR/INDR instruction group
* Added OUTI/OUTD/OTIR/OTDR instruction group
Revision 1.0:
* First release! The whole thing is new!
ASSEMBLING FOR USE WITH WATCOM C/C++
------------------------------------
Watcom, by default, uses register calling conventions, as does MZ80. To
create a proper emulator for Watcom:
makez80 MZ80.asm -x86
From here:
nasm -f win32 MZ80.asm
Link the MZ80.obj with your Watcom linker.
ASSEMBLING FOR USE WITH MICROSOFT VISUAL C++ AND BORLAND C++
--------------------------------------------------------------------
Visual C++ and Borland C++ use stack calling conventions by default. To
create a proper emulator for these compilers:
makez80 MZ80.asm -s -x86
For Visual C++ or Borland C++:
nasm -f win32 MZ80.asm
Link with your standard Visual C++ or Borland C++.
ASSEMBLING FOR USE WITH DJGPP, GCC/FREEBSD, OR GCC/LINUX
--------------------------------------------------------------------
DJGPP Uses stack calling conventions:
makez80 MZ80.asm -s -x86
To assemble:
nasm -f coff MZ80.asm
Link with your standard DJGPP linker. The same holds true for GCC under
FreeBSD or Linux. If you're using GCC, use the -l option to generate "plain"
labels so that gcc's linker will properly link things.
MAKEZ80 COMMAND LINE OPTIONS
----------------------------
-s - Use stack calling conventions (DJGPP, MSVC, Borland, etc...)
-cs - Force all stack operations to go through the Read/Write memory handlers.
This slows things down, but is useful when needed.
-16 - Treat all I/O input and output as 16 bit (BC)
-l - Create 'plain' labels - ones without leading and trailing underscores
-nt - Do not generate timing code - this speeds the emulator up, but the
downside is that no timing info is available.
-c - Emit a C mz80 emulator (API Compatible with the assembly version -
handy for porters!)
-x86 - Emit an assembly (x86) mz80 emulator
-os2 - Generate OS/2 compatible segmentation
IMPORTANT NOTE ABOUT INTERRUPTS
-------------------------------
A minor change was made between the 3.1 and 3.2 versions of makez80 in the
way that interrupts were handled.
On a real Z80, the !INT line is a level triggered interrupt, meaning that if
the interrupt line is held low, the Z80 will continue to take interrupts
immediately after the instruction after the EI instruction is executed until
the interrupt line is high again.
In 3.1, if an interrupt came in and interrupts were disabled, the interrupt
would never be "latched" for later execution. The Z80 does not have any
internal latching capabilities, however external hardware often does hold
the interrupt line low until the interrupt is executed, in effect, a latch.
I've only found one video game so far that requires the "raising/lowering"
of the interrupt line (Ataxx). In the games that I've tried, it has improved
performance, in some cases drastically, and in others not at all. This can
be accounted for by interrupts being taken now, where they were being dropped
in prior mz80 releases.
mz80 Emulates the most commonly used scenario. Now when mz80int() is executed
and a nonzero value is returned (indicating interrupts were disabled), it
will set z80intPending, and the interrupt will be taken after execution of
one instruction beyond the EI instruction.
So now, if mz80int() returns a nonzero value, that means an interrupt is
latched. If clearing this latch is desired or the old behavior of 3.1 is
desired, make a call to the mz80ClearPendingInterrupt() call. It's a 2
instruction call that has extremely small overhead and will not affect
performance in any measurable way.
In any case, MZ80 will now execute one instruction after EI regardless of
how much time is available to avoid the possibility of an interrupt request
coming in directly after the EI instruction.
STEPS TO EMULATION
------------------
NOTE: -16 Is a command line option that will treat all I/O as 16 bit. That
is, in an instruction like "IN AL, (C)", the addressed passed to the I/O
handler will be BC instead of just C. Bear this in mind when considering your
emulated platform.
There are a few steps you want to go through to get proper emulation, and a
few guidelines must be followed.
1) Create a MZ80CONTEXT
2) Create your virtual 64K memory space using whatever means of obtaining
memory you need to do.
3) Set mz80Base in your context to be the base of your 64K memory space
4) Load up your image to be emulated within that 64K address space.
5) Set z80IoRead and z80IoWrite to their appropriate structure arrays. Here's
an example:
struct z80PortRead ReadPorts[] =
{
{0x10, 0x1f, SoundChip1Read},
{0x20, 0x2f, SoundChip2Read}
{(UINT32) -1, (UINT32) -1, NULL}
};
When an IN instruction occurs, mz80 will probe this table looking for a
handler to the address of the "IN" instruction. If it is found in the list,
it's up to the handler to return the proper value. Otherwise, a value of
0ffh is returned internally if no handler for that I/O address is found. In
the case above, SoundChip1Read is called when the I/O address is between 0x10-
0x1f. A similar structure is used for I/O writes as well (OUT):
struct z80PortWrite WritePorts[] =
{
{0x20, 0x2f, SoundChip2Write},
{0x30, 0x36, VideoCtrlWrite},
{(UINT32) -1, (UINT32) -1, NULL}
}
Of course, this does the opposite that the z80PortRead struct, and instead
looks for a handler to hand some data to. If it doesn't find an appropriate
handler, nothing happens.
6) Set mz80MemoryRead & mz80MemoryWrite to their appropriate structure
arrays. Here is an example:
struct MemoryWriteByte GameWrite[] =
{
{0x3000, 0x3fff, VideoWrite},
{0x4000, 0x4fff, SpriteWrite},
{(UINT32) -1, (UINT32) -1, NULL}
};
The above example says that any time a write occurs in the 0x3000-0x3fff
range, call the VideoWrite routine. The same holds true for the SpriteWrite
region as well.
NOTE: When your write handler is called, it is passed the address of the
write and the data that is to be written to it. If your handler doesn't
write the data to the virtual image, the mz80 internal code will not.
NOTE: These routines will *NOT* be called when execution asks for these
addresses. It will only call them when a particular instruction uses the
memory at these locations.
If you wish for a region to be RAM, just leave it out of your memory region
exception list. The WriteMemoryByte routine will treat it as read/write
RAM and will write to mz80Base + addr directly.
If you wish to protect ROM regions (not often necessary), create a range that
encompasses the ROM image, and have it call a routine that does nothing. This
will prevent data from being written back onto the ROM image.
Leave your last entry in the table as shown above, with a null handler and
0xffffffff-0xffffffff as your read address. Even though the Z80 only
addresses 64K of space, the read/write handlers are defined as 32 bit so
the compiler won't pass junk in the upper 16 bits of the address lines. Not
only that, it allows orthoganality for future CPU emulators that may use
these upper bits.
You can do a mz80GetContext() if you'd like to read the current context of
the registers. Note that by the time your handler gets called, the program
counter will be pointing to the *NEXT* instruction.
struct MemoryReadByte GameRead[] =
{
{0x2000, 0x200f, ReadHandler},
{(UINT32) -1, (UINT32) -1, NULL}
};
Same story here. If you have a special handler for an attempted read at a
particular address, place its range in this table and create a handler
routine for it.
If you don't define a handler for a particular region, then the ReadMemoryByte
in mz80.ASM will actually read the value out of mz80Base + the offset
required to complete the instruction.
7) Set the intAddr and nmiAddr to the addresses where you want mz80 to start
executing when an interrupt or NMI happens. Take a look at the section
entitled "INTERRUPTS" below for more information on this.
8) Call mz80SetContext() on your Z80 context
9) Call mz80Reset(). This will prime the program counter and cause a virtual
CPU-wide reset.
10) Once you have those defined, you're ready to begin emulation. There's some
sort of main loop that you'll want. Maybe something like:
while (hit == 0)
{
if (lastSec != (UINT32) time(0))
{
diff = (mz80clockticks - prior) / 3000000;
printf("%ld Clockticks, %ld frames, %ld Times original speed\n", MZ80clockticks - prior, frames, diff);
frames = 0;
prior = mz80clockticks;
lastSec = time(0);
if (kbhit())
{
getch();
hit = 1;
}
}
/* 9000 Cycles per NMI (~3 milliseconds @ 3MHZ) */
dwResult = mz80exec(9000);
mz80clockticks += mz80GetElapsedTicks(TRUE);
mz80nmi();
/* If the result is not 0x80000000, it's an address where
an invalid instruction was hit. */
if (0x80000000 != dwResult)
{
mz80GetContext(&sCpu1);
printf("Invalid instruction at %.2x\n", sCpu1.MZ80pc);
exit(1);
}
}
Call mz80exec() With the # of virtual CPU cycles you'd like mz80 to
execute. Be sure to use the mz80GetElapsedTicks() call *AFTER* execution to
see how many virtual CPU cycles it actually executed. For example, if you tell
mz80 to execute 500 virtual CPU cycles, it will execute slightly more. Anything
from 500 to 524 (24 cycles being the longest any 1 instruction takes in the
Z80).
Use the mz80GetElapsedTicks() call for more accurate cycle counting. Of course,
this is only if you have *NOT* included the -nt option.
If you pass FALSE to the mz80GetElapsedTicks() function, the internal CPU
elapsed tick clock will not be reset. The elapsed tick counter is something
that continues to increase every emulated instruction, and like an odometer,
will keep counting unless you pass TRUE to mz80GetElapsedTicks(), of which
case it will return you the current value of the elapsed ticks and set it to
0 when complete.
NOTE: The bigger value you pass to mz80exec, the greater benefit you get out
of the virtual registers persisting within the emulator, and it will run
faster. Pass in a value that is large enough to take advantage of it, but
not so often that you can't handle nmi or int's properly.
If you wish to create a virtual NMI, call mz80nmi(), and it will be taken
the next time you call mz80exec, or alternately if you have a handler call
mz80nmi/mz80int(), the interrupt will be taken upon return. Note that
mz80nmi() doesn't actually execute any code - it only primes the emulator to
begin executing NMI/INT code.
NOTE: mz80int() is defined with a UINT32 as a formal parameter. Depending
upon what interrupt mode you're executing in (described later), it may or may
not take a value.
NMI's can interrupt interrupts, but not the other way around - just like a
real Z80. If your program is already in an interrupt, another one will not be
taken. The same holds true for an NMI - Just like a real Z80!
MUTLI-PROCESSOR NOTES
---------------------
Doing multi processor support is a bit trickier, but is still fairly straight-
forward.
For each processor to be emulated, go through steps 1-7 above - giving each
CPU its own memory space, register storage, and read/write handlers.
EXECUTION OF MULTI-CPUS:
-------------------------
When you're ready to execute a given CPU, do the following:
mz80SetContext(contextPointer);
This will load up all information saved before into the emulator and ready it
for execution. Then execute step 7 above to do your virtual NMI's, interrupts,
etc... All CPU state information is saved within a context.
When the execution cycle is complete, do the following to save the updated
context away for later:
mz80GetContext(contextPointer);
Give each virtual processor a slice of time to execute. Don't make the values
too small or it will spend its time swapping contexts. While this in itself
isn't particularly CPU expensive, the more time you spend executing the better.
mz80 Keeps all of the Z80 register in native x86 register (including most
of the flags, HL, BC, and A). If no context swap is needed, then you get the
added advantage of the register storage. For example, let's say you were
running two Z80s - one at 2.0MHZ and one at 3.0MHZ. An example like this
might be desirable:
mz80SetContext(cpu1Context); // Set CPU #1's information
mz80exec(2000); // 2000 Instructions for 2.0MHZ CPU
mz80GetContext(cpu1Context); // Get CPU #1's state info
mz80SetContext(cpu2Context); // Set CPU #2's state information
mz80exec(3000); // 3000 Instructions for 3.0MHZ CPU
mz80GetContext(cpu2Context); // Get CPU #2's state information
This isn't entirely realistic, but if you keep the instruction or timing
ratios between the emulated CPUs even, then timing is a bit more accurate.
NOTE: If you need to make a particular CPU give up its own time cycle because
of a memory read/write, simply trap a particular address (say, a write to a
slave processor) and call mz80ReleaseTimeslice(). It will not execute any
further instructions, and will give up its timeslice. Put this in your
read/write memory trap.
NOTE: You are responsible for "holding back" the processor emulator from
running too fast.
INTERRUPTS
----------
The Z80 has three interrupt modes: IM 0 - IM 2. Each act differently. Here's
a description of each:
IM 0
This mode will cause the Z80 to be able to pull a "single byte instruction"
off the bus when an interrupt occurs. Since we're not doing bus cycle
emulation, it acts identically to mode 1 (described below). The formal
parameter to mz80int() is ignored. There is really no point in actually
emulating the instruction execution since any instruction that would be
executed would be a branch instruction!
IM 1
This mode is the "default" mode that the Z80 (and mz80 for that matter) comes
up in. When you call mz80reset(), the interrupt address is set to 38h and
the NMI address is set to 66h. So when you're in IM 1 and mz80int() is
called, the formal parameter is ignored and the z80intAddr/z80nmiAddr values
are appropriately loaded into the program counter.
IM 2
This mode causes the Z80 to read the upper 8 bits from the current value
of the "I" register, and the lower 8 bits from the value passed into mz80int().
So, if I contained 35h, and you did an mz80int(0x64), then an interrupt at
address 3564h would be taken. Simple!
OTHER GOODIES
-------------
MZ80 Has a nice feature for allowing the same handler to handle different
data regions on a single handler. Here's an example:
struct PokeyDataStruct Pokey1;
struct PokeyDataStruct Pokey2;
struct MemoryWriteByte GameWrite[] =
{
{0x1000, 0x100f, PokeyHandler, Pokey1},
{0x1010, 0x101f, PokeyHandler, Pokey2},
{(UINT32) -1, (UINT32) -1, NULL}
};
void PokeyHandler(UINT32 dwAddr, UINT8 bData, struct sMemoryWriteByte *psMem)
{
struct PokeyDataStruct *psPokey = psMem->pUserArea;
// Do stuff with psPokey here....
}
This passes in the pointer to the sMemoryWriteByte structure that caused
the handler to be called. The pUserArea is a user defined address that can
be anything. It is not necessary to fill it in with anything or even
initialize it if the handler doesn't actually use it.
This allows a single handler to handle multiple data references. This is
particularly useful when handling sound chip emulation, where there might
be more than one of a given device. Sure beats having multiple unique
handlers that are identical with the exception of the data area where it
writes! This allows a good deal of flexibility.
The same construct holds for MemoryReadByte, z80PortRead, and z80PortWrite,
so all can take advantage of this feature.
SHARED MEMORY FEATURES
----------------------
MZ80 Also has another useful feature for dealing with shared memory regions:
UINT8 bSharedRAM[0x100];
struct MemoryWriteByte Processor1[] =
{
{0x1000, 0x10ff, NULL, bSharedRAM},
{(UINT32) -1, (UINT32) -1, NULL}
};
struct MemoryWriteByte Processor2[] =
{
{0x1000, 0x10ff, NULL, bSharedRAM},
{(UINT32) -1, (UINT32) -1, NULL}
};
If the handler address is NULL, mz80 will look at the pUserArea field as a
pointer to RAM to read from/write to. This comes in extremely handy when you
have an emulation that requires two or more processors writing to the same
memory block. And it's lots faster than creating a handler that writes to
a common area as well.
DEBUGGING
---------
Several new functions have been added to mz80 that assist the emulator
author by providing a standard set of functions for register access:
UINT8 mz80SetRegisterValue(void *pContext, UINT32 dwRegister, UINT32 dwValue)
This allows setting of any register within the Z80. The register field can be
one of the following values (defined in mz80.h):
CPUREG_PC
CPUREG_Z80_AF
CPUREG_Z80_BC
CPUREG_Z80_DE
CPUREG_Z80_HL
CPUREG_Z80_AFPRIME
CPUREG_Z80_BCPRIME
CPUREG_Z80_DEPRIME
CPUREG_Z80_HLPRIME
CPUREG_Z80_IX
CPUREG_Z80_IY
CPUREG_Z80_SP
CPUREG_Z80_I
CPUREG_Z80_R
CPUREG_Z80_A
CPUREG_Z80_B
CPUREG_Z80_C
CPUREG_Z80_D
CPUREG_Z80_E
CPUREG_Z80_H
CPUREG_Z80_L
CPUREG_Z80_F
CPUREG_Z80_CARRY
CPUREG_Z80_NEGATIVE
CPUREG_Z80_PARITY
CPUREG_Z80_OVERFLOW
CPUREG_Z80_HALFCARRY
CPUREG_Z80_ZERO
CPUREG_Z80_SIGN
CPUREG_Z80_IFF1
CPUREG_Z80_IFF2
Each individual register's value can be set, including the flags at the end.
The only valid values for the flags are 1 and 0. Setting these will
automatically adjust the "F" register.
If pContext is NULL, then the registers in the currently active context are
changed. If pContext points to a non-NULL area, that area is assumed to be
a CONTEXTMZ80 structure where the new register value will be written.
If mz80SetRegisterValue() returns a nonzero value, either the register value
or register is out of range or invalid.
UINT32 mz80GetRegisterValue(void *pContext, UINT32 dwRegister)
This returns the value of the register given on input (listed above as
CPUREG_Z80_xxxxx). Flag values will be 1 or 0.
If pContext is NULL, then the registers in the currently active context are
read. If pContext points to a non-NULL area, that area is assumed to be
a CONTEXTMZ80 structure from which register values are pulled.
UINT32 mz80GetRegisterTextValue(void *pContext, UINT32 dwRegister,
UINT8 *pbTextArea)
This returns the textual representation of the value of a given register.
It is a text printable string that can be used in sprintf() statements and
the like. This function is useful because different representations for
registers (like flags) can be a group of 8 flag bytes instead of a single
value.
On entry, pContext being set to NULL indicates that mz80 should get the
register value from the currently active context. Otherwise, it is assumed
to be pointing to a CONTEXTMZ80 structure, which contains the value of the
registers to be read.
pbTextArea points to a buffer where the value text can be written. This points
to a user supplied buffer.
On exit, if any nonzero value is encountered, either the register # is out
of range or pbTextArea is NULL.
UINT8 *mz80GetRegisterName(UINT32 dwRegister)
This returns a pointer to the textual name of the register passed in. NULL
Is returned if the register index (CPUREG_Z80_xxxx table described above) is
out of range. DO NOT MODIFY THE TEXT! It is static data.
FINAL NOTES
-----------
I have debugged MZ80.ASM to the best of my abilities. There might still be
a few bugs floating around in it, but I'm not aware of any. I've validated
all instructions (That I could) against a custom built Z80 on an ISA card
(that fits in a PC) so I'm quite confident that it works just like a real
Z80.
If you see any problems, please point them out to me, as I am eager to make
mz80 the best emulator that I can.
If you have questions, comments, etc... about mz80, please don't hesitate
to send me an email. And if you use mz80 in your emulator, I'd love to take
a look at your work. If you have special needs, or need implementation
specific hints, feel free to email me, Neil Bradley (neil@synthcom.com). I
will do my best to help you.
Enjoy!
Neil Bradley
neil@synthcom.com

View file

@ -225,13 +225,6 @@ extern short *PsndOut;
extern void (*PsndMix_32_to_16l)(short *dest, int *src, int count);
void PsndRerate(int preserve_state);
// Utils.c
extern int PicuAnd;
int PicuQuick(unsigned short *dest,unsigned short *src);
int PicuShrink(unsigned short *dest,int destLen,unsigned short *src,int srcLen);
int PicuShrinkReverse(unsigned short *dest,int destLen,unsigned short *src,int srcLen);
int PicuMerge(unsigned short *dest,int destLen,unsigned short *src,int srcLen);
#ifdef __cplusplus
} // End of extern "C"
#endif

View file

@ -1,108 +0,0 @@
// This is part of Pico Library
// (c) Copyright 2004 Dave, All rights reserved.
// (c) Copyright 2006 notaz, All rights reserved.
// Free for non-commercial use.
// For commercial use, separate licencing terms must be obtained.
#include "pico_int.h"
int PicuAnd=0xf7de;
// Quick low-quality conversion of 320 to 176:
int PicuQuick(unsigned short *dest,unsigned short *src)
{
unsigned short *end=NULL;
src+=13; end=src+290;
dest++;
do
{
*dest++=*src++;
*dest++=*src; src+=2;
*dest++=*src; src+=2;
*dest++=*src++;
*dest++=*src; src+=2;
*dest++=*src; src+=2;
}
while (src<end);
return 0;
}
// Shrink the pixels in src/srcLen, to the screen line pointed to by dest/destLen
int PicuShrink(unsigned short *dest,int destLen,unsigned short *src,int srcLen)
{
unsigned short *end=NULL;
int bias=0,pa=0,sub=0;
end=dest+destLen;
sub=srcLen-destLen;
do
{
pa=*src++; bias-=sub;
if (bias<0) { pa+=*src++; pa>>=1; bias+=destLen; }
*dest++=(unsigned short)pa;
pa=*src++; bias-=sub;
if (bias<0) { pa+=*src++; pa>>=1; bias+=destLen; }
*dest++=(unsigned short)pa;
}
while (dest<end);
return 0;
}
// same thing, only reversed (dest is in pre-decremental mode)
int PicuShrinkReverse(unsigned short *dest,int destLen,unsigned short *src,int srcLen)
{
unsigned short *end=NULL;
int bias=0,pa=0,sub=0;
end=dest-destLen;
sub=srcLen-destLen;
do
{
pa=*src++; bias-=sub;
if (bias<0) { pa+=*src++; pa>>=1; bias+=destLen; }
*(--dest)=(unsigned short)pa;
pa=*src++; bias-=sub;
if (bias<0) { pa+=*src++; pa>>=1; bias+=destLen; }
*(--dest)=(unsigned short)pa;
}
while (dest>end);
return 0;
}
int PicuMerge(unsigned short *dest,int destLen,unsigned short *src,int srcLen)
{
unsigned short *end=NULL;
int bias=0,pa=0,mask=PicuAnd,sub=0;
end=dest+destLen;
sub=srcLen-destLen;
do
{
pa=*src++; bias-=sub;
if (bias<0) { pa+=*src++; pa>>=1; bias+=destLen; }
pa&=mask; pa+=(*dest)&mask; pa>>=1;
*dest++=(unsigned short)pa;
pa=*src++; bias-=sub;
if (bias<0) { pa+=*src++; pa>>=1; bias+=destLen; }
pa&=mask; pa+=(*dest)&mask; pa>>=1;
*dest++=(unsigned short)pa;
}
while (dest<end);
return 0;
}

View file

@ -1,69 +0,0 @@
// protocol used to talk between exe and it's launcher
#ifndef __CLIENTSERVER_H
#define __CLIENTSERVER_H
#include <w32std.h>
// names
_LIT(KServerName, "PicodriveNServ");
_LIT(KServerWGName, "Picosmall"); // window group name
_LIT(KClientName, "PicodriveN");
_LIT(KClientFind, "PicodriveN*"); // client search mask (for TFindLibrary)
// opcodes used in message passing between client and server
enum TPicoServRqst {
PicoMsgLoadState,
PicoMsgSaveState,
PicoMsgLoadROM,
PicoMsgResume,
PicoMsgReset,
PicoMsgKeys,
PicoMsgPause,
PicoMsgQuit,
PicoMsgConfigChange, // launcher -> emu
PicoMsgRetrieveConfig, // emu -> launcher
PicoMsgRetrieveDebugStr,// fixed to 512 bytes 4 now
kDefaultMessageSlots // this is how many messages we need :)
};
// event messages to launcher
enum TPicoLauncherEvents {
EEventKeyCfgDone = EEventUser + 1,
EEventGamePaused,
};
// configuration data to be sent between server and client
struct TPicoConfig {
enum TPicoScreenRotation {
PRot0,
PRot90,
PRot180,
PRot270
};
enum TPicoScreenMode {
PMCenter,
PMFit,
PMFit2
};
enum TPicoFrameSkip {
PFSkipAuto = -1,
PFSkip0
};
TInt32 iScreenRotation;
TInt32 iScreenMode;
TUint32 iFlags; // LSb->MSb: use_sram, show_fps, enable_sound, sound_rate(3bits), gzip_saves{=0x40}, dont_use_mot_vol
// enable_ym2612&dac, enable_sn76496, enable_z80, stereo_sound;
// alt_renderer, 6button_gamepad, accurate_timing
TInt32 iPicoOpt;
TInt32 iFrameskip;
TUint32 iKeyBinds[32];
TUint32 iAreaBinds[19];
TInt32 PicoRegion;
};
#endif // __CLIENTSERVER_H

View file

@ -1,321 +0,0 @@
# environmental vars required:
# EPOCROOT2 - root of your SDK with slash at the end
# settings
#dprint = 1
#mz80 = 1
#debug_cyclone = 1
asm_memory = 1
#asm_render = 1
#use_musashi = 1
EPOCBLDUREL = _BUILD
EPOCTRGUREL = $(EPOCROOT2)EPOC32\RELEASE\ARMI\UREL
EPOCLINKUREL = $(EPOCTRGUREL)
EPOCSTATLINKUREL = $(EPOCTRGUREL)
# must set both PATH and Path to make it work correctly (?)
Path:=$(EPOCROOT2)EPOC32\gcc\bin;$(Path)
PATH:=$(Path)
ERASE = @erase 2>>nul
ALL : UREL
UREL : CHECKENV MAKEDIRS
UREL : $(EPOCTRGUREL)\PICOSMALL.EXE
CLEAN :
@perl -S ermdir.pl "$(EPOCBLDUREL)"
@del *.o 2> NUL
CLEANZ :
del ..\..\zlib\*.o 2> NUL
CLEANM :
del ..\..\musashi\*.o 2> NUL
CLEANALL : CLEAN CLEANZ CLEANM
# check for EPOCROOT2
CHECKENV : $(EPOCROOT2)epoc32
$(EPOCROOT2)epoc32 :
@echo Please set EPOCROOT2 environmental variable to full path to your SDK
@echo with ending slash (something like C:\Uiq_21\)
@cd : 2> NUL # do something stupid to make it silently fail
# GCC
INCDIR = -I. -I "..\..\" -I "$(EPOCROOT2)EPOC32\INCLUDE" -I "$(EPOCROOT2)EPOC32\INCLUDE\LIBC"
GCCFLAGS = -nostdinc -Wall -Wno-ctor-dtor-privacy -Wno-unknown-pragmas -march=armv4t -mthumb-interwork -pipe -O3 -fomit-frame-pointer
GCCDEFS = -D__SYMBIAN32__ -D__GCC32__ -D__EPOC32__ -D__MARM__ -D__MARM_ARMI__ -D__EXE__ -DNDEBUG -D_UNICODE -DARM
# dprint
ifeq "$(dprint)" "1"
GCCDEFS += -D__DEBUG_PRINT
endif
# drz80/mz80
ifeq "$(mz80)" "1"
GCCDEFS += -D_USE_MZ80
else
GCCDEFS += -D_USE_DRZ80
endif
# debug_cyclone
ifeq "$(debug_cyclone)" "1"
use_musashi := 1
GCCDEFS += -DEMU_C68K
asm_memory := 0
endif
# musashi
ifeq "$(use_musashi)" "1"
GCCDEFS += -DEMU_M68K
else
GCCDEFS += -DEMU_C68K
endif
GCC = gcc -c $(GCCFLAGS) $(GCCDEFS) $(INCDIR)
LIBSUREL = \
$(EPOCSTATLINKUREL)\EGCC.LIB \
$(EPOCLINKUREL)\ESTLIB.LIB \
$(EPOCLINKUREL)\WS32.LIB \
$(EPOCLINKUREL)\HAL.LIB \
$(EPOCLINKUREL)\EUSER.LIB \
$(EPOCLINKUREL)\EFSRV.LIB \
$(EPOCLINKUREL)\EZLIB.LIB
$(EPOCTRGUREL)\PICOSMALL.EXE : $(EPOCBLDUREL)\PICOSMALL.in $(EPOCSTATLINKUREL)\EEXE.LIB $(LIBSUREL)
@echo * linking and finishing
@ld -s -e _E32Startup -u _E32Startup \
--base-file "$(EPOCBLDUREL)\PICOSMALL.bas" -o "$(EPOCBLDUREL)\PICOSMALL.EXE" \
"$(EPOCSTATLINKUREL)\EEXE.LIB" --whole-archive "$(EPOCBLDUREL)\PICOSMALL.in" \
--no-whole-archive $(LIBSUREL) $(USERLDFLAGS)
-$(ERASE) "$(EPOCBLDUREL)\PICOSMALL.EXE"
@dlltool -m arm_interwork \
--base-file "$(EPOCBLDUREL)\PICOSMALL.bas" \
--output-exp "$(EPOCBLDUREL)\PICOSMALL.exp"
-$(ERASE) "$(EPOCBLDUREL)\PICOSMALL.bas"
@ld -s -e _E32Startup -u _E32Startup \
"$(EPOCBLDUREL)\PICOSMALL.exp" \
-Map "$(EPOCBLDUREL)\PICOSMALL.EXE.map" -o "$(EPOCBLDUREL)\PICOSMALL.EXE" \
"$(EPOCSTATLINKUREL)\EEXE.LIB" --whole-archive "$(EPOCBLDUREL)\PICOSMALL.in" \
--no-whole-archive $(LIBSUREL) $(USERLDFLAGS)
-$(ERASE) "$(EPOCBLDUREL)\PICOSMALL.exp"
ifeq "$(noecompxl)" "1"
@petran "$(EPOCBLDUREL)\PICOSMALL.EXE" "$@" \
-nocall -uid1 0x1000007a -uid2 0x00000000 -uid3 0x00000000 \
-heap 0x00000001 0x00800000
else
@petran_ "$(EPOCBLDUREL)\PICOSMALL.EXE" "$@" \
-nocall -uid1 0x1000007a -uid2 0x00000000 -uid3 0x00000000 \
-heap 0x00000001 0x00800000 -stack 0x80000000
endif
# -$(ERASE) "$(EPOCBLDUREL)\PICOSMALL.EXE"
@perl -S ecopyfile.pl "$@" "PICOSMALL.EXE"
ifeq "$(up)" "1"
@quploadpico.cmd
endif
OBJECTSUREL= \
$(EPOCBLDUREL)\debug.o \
$(EPOCBLDUREL)\CART.o \
$(EPOCBLDUREL)\DRAW.o \
$(EPOCBLDUREL)\DRAW2.o \
$(EPOCBLDUREL)\MAIN.o \
$(EPOCBLDUREL)\MEMORY.o \
$(EPOCBLDUREL)\PICO.o \
$(EPOCBLDUREL)\SEK.o \
$(EPOCBLDUREL)\VIDEOPORT.o \
$(EPOCBLDUREL)\SIMPLESERVER.o \
$(EPOCBLDUREL)\VID.o \
$(EPOCBLDUREL)\Utils.o \
$(EPOCBLDUREL)\Area.o \
$(EPOCBLDUREL)\Misc.o \
$(EPOCBLDUREL)\unzip.o \
..\..\zlib\gzio_symb.o \
$(EPOCBLDUREL)\sound.o \
$(EPOCBLDUREL)\sn76496.o \
$(EPOCBLDUREL)\ym2612.o \
$(EPOCBLDUREL)\blit.o
ifeq "$(debug_cyclone)" "1"
OBJECTSUREL += $(EPOCBLDUREL)\Cyclone.o $(EPOCBLDUREL)\_cyclone_debug.o
endif
# the MUSASHI core
ifeq "$(use_musashi)" "1"
OBJECTSUREL += \
..\..\musashi\m68kcpu.o \
..\..\musashi\m68kops.o \
..\..\musashi\m68kopac.o \
..\..\musashi\m68kopdm.o \
..\..\musashi\m68kopnz.o \
..\..\musashi\m68kdasm.o
else
OBJECTSUREL += $(EPOCBLDUREL)\Cyclone.o
endif
ifeq "$(mz80)" "1"
OBJECTSUREL := $(OBJECTSUREL) $(EPOCBLDUREL)\mz80.o
else
OBJECTSUREL := $(OBJECTSUREL) $(EPOCBLDUREL)\DrZ80.o
endif
ifeq "$(asm_memory)" "1"
ASMDEFINES += -D_ASM_MEMORY_C
OBJECTSUREL := $(OBJECTSUREL) $(EPOCBLDUREL)\memory_asm.o
endif
ifeq "$(asm_render)" "1"
ASMDEFINES += -D_ASM_DRAW_C
OBJECTSUREL := $(OBJECTSUREL) $(EPOCBLDUREL)\draw_asm.o $(EPOCBLDUREL)\draw2_asm.o
endif
$(EPOCBLDUREL)\PICOSMALL.in : $(OBJECTSUREL)
@echo * ar
@if exist "$@" del "$@"
@ar cr $@ $^
..\..\Cyclone\proj\Cyclone.s :
@echo You need to build Cyclone first. See Cyclone.txt in cyclone directory.
@cd : 2> NUL # do something stupid to make it silently fail
$(EPOCBLDUREL)\Cyclone.o : ..\..\Cyclone\proj\Cyclone.s
@echo * assembling Cyclone..
@as -marmv4t -mthumb-interwork -o $@ $^
$(EPOCBLDUREL)\DrZ80.o : ..\..\pico\sound\DrZ80.s ..\..\pico\sound\DrZ80.h
@echo * assembling DrZ80..
@as -marmv4t -mthumb-interwork -o $@ ..\..\pico\sound\DrZ80.s
# Source
$(EPOCBLDUREL)\debug.o : debug.cpp debug.h
@echo * debug.cpp
@$(GCC) -o $@ debug.cpp
$(EPOCBLDUREL)\MAIN.o : Main.cpp ..\..\pico\picoInt.h vid.h SimpleServer.h ClientServer.h audio.h debug.h
@echo * Main.cpp
@$(GCC) -o $@ "Main.cpp"
$(EPOCBLDUREL)\VID.o : VID.cpp vid.h ClientServer.h ..\..\pico\picoInt.h
@echo * Vid.cpp
@$(GCC) -o $@ "VID.cpp"
$(EPOCBLDUREL)\SIMPLESERVER.o : SIMPLESERVER.cpp version.h ClientServer.h SimpleServer.h ..\..\pico\picoInt.h debug.h
@echo * SimpleServer.cpp
@$(GCC) -o $@ "SIMPLESERVER.cpp"
$(EPOCBLDUREL)\CART.o : ..\..\pico\Cart.c ..\..\pico\picoInt.h ..\..\pico\Pico.h ..\..\unzip\unzip.h
@echo * Cart.c
@$(GCC) -D_UNZIP_SUPPORT -o $@ "..\..\pico\Cart.c"
$(EPOCBLDUREL)\DRAW.o : ..\..\pico\Draw.c ..\..\pico\picoInt.h ..\..\pico\Pico.h
@echo * Draw.c
@$(GCC) $(ASMDEFINES) -o $@ "..\..\pico\Draw.c"
#
$(EPOCBLDUREL)\DRAW2.o : ..\..\pico\Draw2.c ..\..\pico\picoInt.h ..\..\pico\Pico.h
@echo * Draw2.c
@$(GCC) $(ASMDEFINES) -o $@ "..\..\pico\Draw2.c"
$(EPOCBLDUREL)\MEMORY.o : ..\..\pico\Memory.c ..\..\pico\picoInt.h ..\..\pico\Pico.h
@echo * Memory.c
@$(GCC) $(ASMDEFINES) -o $@ "..\..\pico\Memory.c"
$(EPOCBLDUREL)\PICO.o : ..\..\pico\Pico.c ..\..\pico\picoInt.h ..\..\pico\Pico.h
@echo * Pico.c
@$(GCC) -o $@ "..\..\pico\Pico.c"
$(EPOCBLDUREL)\SEK.o : ..\..\pico\Sek.c ..\..\pico\picoInt.h ..\..\pico\Pico.h
@echo * Sek.c
@$(GCC) -o $@ "..\..\pico\Sek.c"
$(EPOCBLDUREL)\VIDEOPORT.o : ..\..\pico\Videoport.c ..\..\pico\picoInt.h ..\..\pico\Pico.h
@echo * Videoport.c
@$(GCC) -o $@ "..\..\pico\Videoport.c"
$(EPOCBLDUREL)\Utils.o : ..\..\pico\Utils.c ..\..\pico\picoInt.h ..\..\pico\Pico.h
@echo * Utils.c
@$(GCC) -o $@ "..\..\pico\Utils.c"
$(EPOCBLDUREL)\Area.o : ..\..\pico\Area.c ..\..\pico\picoInt.h ..\..\pico\Pico.h
@echo * Area.c
@$(GCC) -o $@ "..\..\pico\Area.c"
$(EPOCBLDUREL)\Misc.o : ..\..\pico\Misc.c ..\..\pico\picoInt.h ..\..\pico\Pico.h
@echo * Misc.c
@$(GCC) -o $@ "..\..\pico\Misc.c"
$(EPOCBLDUREL)\unzip.o : ..\..\unzip\unzip.c ..\..\unzip\unzip.h
@echo * unzip.c
@$(GCC) -o $@ "..\..\unzip\unzip.c"
# assembly "optimized" stuff
$(EPOCBLDUREL)\blit.o : blit.s
@echo * blit.s
@as -marmv4t -mthumb-interwork -o $@ blit.s
$(EPOCBLDUREL)\draw_asm.o : ..\..\pico\draw.s
@echo * draw.s
@as -marmv4t -mthumb-interwork -o $@ ..\..\pico\draw.s
$(EPOCBLDUREL)\draw2_asm.o : ..\..\pico\draw2.s
@echo * draw2.s
@as -marmv4t -mthumb-interwork -o $@ ..\..\pico\draw2.s
$(EPOCBLDUREL)\memory_asm.o : ..\..\pico\memory.s
@echo * memory.s
@as -marmv4t -mthumb-interwork -o $@ ..\..\pico\memory.s
# sound stuff
$(EPOCBLDUREL)\sound.o : ..\..\pico\sound\sound.c ..\..\pico\sound\sound.h
@echo * sound.c
@$(GCC) -o $@ "..\..\pico\sound\sound.c"
$(EPOCBLDUREL)\ym2612.o : ..\..\pico\sound\ym2612.c ..\..\pico\sound\ym2612.h ..\..\pico\sound\driver.h
@echo * ym2612.c
@$(GCC) -o $@ "..\..\pico\sound\ym2612.c"
$(EPOCBLDUREL)\sn76496.o : ..\..\pico\sound\sn76496.c ..\..\pico\sound\sn76496.h ..\..\pico\sound\driver.h
@echo * sn76496.c
@$(GCC) -o $@ "..\..\pico\sound\sn76496.c"
$(EPOCBLDUREL)\mz80.o : ..\..\pico\sound\mz80.c ..\..\pico\sound\mz80.h
@echo * mz80.c
@$(GCC) -o $@ "..\..\pico\sound\mz80.c"
# -D__DEBUG_PRINT_SND
# misc
$(EPOCBLDUREL)\_cyclone_debug.o : ..\..\pico\_cyclone_debug.c
@echo * _cyclone_debug.c
@$(GCC) -o $@ "..\..\pico\_cyclone_debug.c"
# generic rule for generic C stuff
.c.o:
@echo * $<
@$(GCC) $< -o $@
# --- SRCFILES END ---
# Rules to create all necessary directories
MAKEDIRS : \
_build
_build :
@echo * making build dir
@perl -S emkdir.pl $@

View file

@ -1,430 +0,0 @@
// SimpleServer.cpp
#include <e32svr.h>
#include <e32math.h>
#include <e32uid.h>
#include <string.h>
#include "debug.h"
#include "version.h"
#include "ClientServer.h"
#include "SimpleServer.h"
#include "pico\picoInt.h"
extern TInt machineUid;
extern int gamestate, gamestate_prev;
extern TPicoConfig currentConfig;
extern TPicoKeyConfigEntry keyConfigMotA[];
extern const char *actionNames[];
const char *RomFileName = 0;
int pico_was_reset = 0;
// utility
unsigned int bigend(unsigned int l)
{
return (l>>24)|((l>>8)&0xff00)|((l<<8)&0xff0000)|(l<<24);
}
//**********************************
//CPicoServServer
//**********************************
CPicoServServer::CPicoServServer(TInt aPriority)
: CServer(aPriority)
{
}
// Create and start a new count server.
void CPicoServServer::New()
{
CPicoServServer *pS=new CPicoServServer(EPriority);
__ASSERT_ALWAYS(pS!=NULL,PanicServer(ESvrCreateServer));
pS->StartL(KServerName);
}
// Create a new server session.
CSharableSession *CPicoServServer::NewSessionL(const TVersion &aVersion) const
{
// check we're the right version
TVersion v(KPicoMajorVersionNumber,KPicoMinorVersionNumber,0);
if (!User::QueryVersionSupported(v,aVersion))
User::Leave(KErrNotSupported);
// make new session
RThread aClient = Message().Client();
return CPicoServSession::NewL(aClient, (CPicoServServer*)this);
}
//**********************************
//CPicoServSession
//**********************************
// constructor - must pass client to CSession
CPicoServSession::CPicoServSession(RThread &aClient, CPicoServServer *aServer)
: CSession(aClient), rom_data(0)
{
// iPicoSvr=aServer;
}
CPicoServSession* CPicoServSession::NewL(RThread &aClient, CPicoServServer * aServer)
{
return new(ELeave) CPicoServSession(aClient,aServer);
}
void CPicoServSession::ServiceL(const RMessage& aMessage)
{
TRAPD(err,DispatchMessageL(aMessage));
aMessage.Complete(err);
}
// service a client request; test the opcode and then do appropriate servicing
void CPicoServSession::DispatchMessageL(const RMessage &aMessage)
{
switch (aMessage.Function()) {
case PicoMsgLoadState:
if(!rom_data) User::Leave(-1); // no ROM
User::LeaveIfError(saveLoadGame(1));
gamestate = PGS_Running;
return;
case PicoMsgSaveState:
if(!rom_data) User::Leave(-1);
User::LeaveIfError(saveLoadGame(0));
gamestate = PGS_Running;
return;
case PicoMsgLoadROM:
loadROM();
return;
case PicoMsgResume:
if(rom_data) gamestate = PGS_Running;
return;
case PicoMsgReset:
if(rom_data) {
PicoReset();
pico_was_reset = 1;
gamestate = PGS_Running;
}
return;
case PicoMsgKeys:
gamestate = PGS_KeyConfig;
return;
case PicoMsgPause:
gamestate = PGS_Paused;
return;
case PicoMsgQuit:
DEBUGPRINT(_L("got quit msg."));
gamestate = PGS_Quit;
return;
// config change
case PicoMsgConfigChange: // launcher -> emu
changeConfig();
return;
case PicoMsgRetrieveConfig: // emu -> launcher
sendConfig();
return;
case PicoMsgRetrieveDebugStr: // emu -> launcher
sendDebug();
return;
// requests we don't understand at all are a different thing,
// so panic the client here, this function also completes the message
default:
PanicClient(EBadRequest);
return;
}
}
void CPicoServSession::loadROM()
{
TInt res;
const TAny* pD=Message().Ptr0();
// TInt desLen=Message().Client().GetDesLength(pD);
if(rom_data) {
// save SRAM for previous ROM
if(currentConfig.iFlags & 1)
saveLoadGame(0, 1);
}
RomFileName = 0;
if(rom_data) {
free(rom_data);
rom_data = 0;
}
// read the contents of the client pointer into a TPtr.
static TBuf8<KMaxFileName> writeBuf;
TRAP(res,Message().ReadL(pD,writeBuf));
if (res!=KErrNone) {
PanicClient(EBadDescriptor);
return;
}
// detect wrong extensions (.srm and .mds)
TBuf8<5> ext;
ext.Copy(writeBuf.Right(4));
ext.LowerCase();
if(!strcmp((char *)ext.PtrZ(), ".srm") || !strcmp((char *)ext.PtrZ(), "s.gz") || // .mds.gz
!strcmp((char *)ext.PtrZ(), ".mds")) {
User::Leave(3);
return;
}
FILE *rom = fopen((char *) writeBuf.PtrZ(), "rb");
if(!rom) {
DEBUGPRINT(_L("failed to open rom."));
User::Leave(1);
return;
}
unsigned int rom_size = 0;
// zipfile support
if(!strcmp((char *)ext.PtrZ(), ".zip")) {
fclose(rom);
res = CartLoadZip((const char *) writeBuf.PtrZ(), &rom_data, &rom_size);
if(res) {
User::Leave(res);
return;
}
} else {
if( (res = PicoCartLoad(rom, &rom_data, &rom_size)) ) {
DEBUGPRINT(_L("PicoCartLoad() failed."));
fclose(rom);
User::Leave(2);
return;
}
fclose(rom);
}
// detect wrong files (Pico crashes on very small files), also see if ROM EP is good
if(rom_size <= 0x200 || strncmp((char *)rom_data, "Pico", 4) == 0 ||
((*(TUint16 *)(rom_data+4)<<16)|(*(TUint16 *)(rom_data+6))) >= (int)rom_size) {
free(rom_data);
rom_data = 0;
User::Leave(3); // not a ROM
}
DEBUGPRINT(_L("PicoCartInsert(0x%08X, %d);"), rom_data, rom_size);
if(PicoCartInsert(rom_data, rom_size)) {
User::Leave(2);
return;
}
pico_was_reset = 1;
// global ROM file name for later use
RomFileName = (const char *) writeBuf.PtrZ();
// load SRAM for this ROM
if(currentConfig.iFlags & 1)
saveLoadGame(1, 1);
// debug
#ifdef __DEBUG_PRINT
TInt cells = User::CountAllocCells();
TInt mem;
User::AllocSize(mem);
DEBUGPRINT(_L("comm: cels=%d, size=%d KB"), cells, mem/1024);
gamestate = PGS_DebugHeap;
gamestate_prev = PGS_Running;
#else
gamestate = PGS_Running;
#endif
}
void CPicoServSession::changeConfig()
{
DEBUGPRINT(_L("got new config."));
// receve it
const TAny* pD=Message().Ptr0();
TPtr8 descr((TUint8*) &currentConfig, sizeof(currentConfig));
TRAPD(res,Message().ReadL(pD, descr));
if (res!=KErrNone) {
PanicClient(EBadDescriptor);
return;
}
// Motorola: enable experimental volume control
if((machineUid&0xfffffff0) == 0x101f6b20) { // Motorolas
if(currentConfig.iFlags & 0x40) {
currentConfig.iKeyBinds[11] = 0x00100000; // vol up
currentConfig.iKeyBinds[12] = 0x00200000; // vol down
keyConfigMotA[11].flags |= 0x40; // add "not configurable" flag
keyConfigMotA[12].flags |= 0x40;
} else {
currentConfig.iKeyBinds[11] &= ~0x00100000; // remove vol actions
currentConfig.iKeyBinds[12] &= ~0x00200000;
keyConfigMotA[11].flags &= ~0x40; // remove "not configurable" flag
keyConfigMotA[12].flags &= ~0x40;
}
}
// set region, PicoOpt and rate
PicoRegionOverride = currentConfig.PicoRegion;
PicoOpt = currentConfig.iPicoOpt;
switch((currentConfig.iFlags>>3)&3) {
case 1: PsndRate=11025; break;
case 2: PsndRate=16000; break;
case 3: PsndRate=22050; break;
default: PsndRate= 8000; break;
}
// 6 button pad, enable XYZM config if needed
if(PicoOpt & 0x20) {
actionNames[8] = "Z";
actionNames[9] = "Y";
actionNames[10] = "X";
actionNames[11] = "MODE";
} else {
actionNames[8] = actionNames[9] = actionNames[10] = actionNames[11] = 0;
}
// if we are in center 90||270 modes, we can bind renderer switcher
if(currentConfig.iScreenMode == TPicoConfig::PMCenter &&
(currentConfig.iScreenRotation == TPicoConfig::PRot90 || currentConfig.iScreenRotation == TPicoConfig::PRot270))
actionNames[25] = "RENDERER";
else actionNames[25] = 0;
}
void CPicoServSession::sendConfig()
{
// send current config to client
currentConfig.iPicoOpt = PicoOpt;
TPtrC8 descr((TUint8*) &currentConfig, sizeof(currentConfig));
Write(Message().Ptr0(), descr);
}
#ifdef __DEBUG_PRINT
extern "C" char *debugString();
#endif
void CPicoServSession::sendDebug()
{
#ifdef __DEBUG_PRINT
char *str = debugString();
// send current config to client
currentConfig.iPicoOpt = PicoOpt;
TPtrC8 descr((TUint8*) str, 1024);
Write(Message().Ptr0(), descr);
#endif
}
// panic the client
void CPicoServSession::PanicClient(TInt aPanic) const
{
Panic(_L("PicoN client"), aPanic);
// client screwed up - there is nothing for us to do now
RProcess me;
me.Terminate(1);
}
// write to the client thread; if unsuccessful, panic the client
void CPicoServSession::Write(const TAny* aPtr,const TDesC8& aDes,TInt anOffset)
{
TRAPD(ret,WriteL(aPtr,aDes,anOffset);)
if (ret!=KErrNone)
PanicClient(EBadDescriptor);
}
//**********************************
//Global functions
//**********************************
// The server thread.
TInt CPicoServServer::ThreadFunction(TAny* anArg)
{
// install our exception hanler first
RThread().SetExceptionHandler(&ExceptionHandler, -1);
// convert argument into semaphore reference
// RSemaphore& semaphore=*(RSemaphore *)anArg;
// start scheduler and server
CActiveScheduler *pA=new CActiveScheduler;
__ASSERT_ALWAYS(pA!=NULL,PanicServer(EMainSchedulerError));
CActiveScheduler::Install(pA);
//CTrapCleanup::New(); // docs say this is created automatically, but I somehow got E32USER-CBase 69 panic
CPicoServServer::New();
// signal that we've started
// semaphore.Signal();
// start fielding requests from clients
CActiveScheduler::Start();
// finished
return(KErrNone);
}
// Panic the server
//GLDEF_C
void PanicServer(TPicoServPanic aPanic)
{
User::Panic(_L("PicoN server"),aPanic);
}
// Create the server thread
// This function is exported from the DLL and called from the client
//EXPORT_C
TInt StartThread()
{
TInt res=KErrNone;
// create server - if one of this name does not already exist
TFindServer findPicoServer(KServerName);
TFullName name;
if(findPicoServer.Next(name) == KErrNone) return -1; // we already exist
RThread thread;
// RSemaphore semaphore;
// semaphore.CreateLocal(0); // create a semaphore so we know when thread finished
res=thread.Create(KServerName, // create new server thread
CPicoServServer::ThreadFunction, // thread's main function
KDefaultStackSize,
KMinHeapSize,
KPicoMaxHeapSize,
// &semaphore // passed as TAny* argument to thread function
0
);
if(res==KErrNone) { // thread created ok - now start it going
thread.SetPriority(EPriorityNormal);
thread.Resume(); // start it going
// semaphore.Wait(); // wait until it's initialized
thread.Close(); // we're no longer interested in the other thread
}
// semaphore.Close();
return res;
}

View file

@ -1,121 +0,0 @@
// SimpleServer.h
#ifndef __SIMPLESERVER_H
#define __SIMPLESERVER_H
#include <e32base.h>
TInt StartThread();
// engine states
enum TPicoGameState {
PGS_Running,
PGS_Paused,
PGS_Quit,
PGS_KeyConfig,
PGS_DebugHeap,
};
// needed for creating server thread.
const TUint KPicoMaxHeapSize=0x00800000;
// reasons for server panic
enum TPicoServPanic
{
EBadRequest,
EBadDescriptor,
EMainSchedulerError,
ESvrCreateServer,
ESvrStartServer,
ECreateTrapCleanup,
ENotImplementedYet,
};
// key config entry (touchpad areas)
struct TPicoAreaConfigEntry {
TRect rect;
//unsigned long actions;
};
struct TPicoKeyConfigEntry
{
unsigned short keyCode;
unsigned char scanCode;
unsigned char flags; // lsb->msb: key_down, pulse_only, ?, ?, ?, ?, not_configurable, disabled
TInt32 handle1; // for CancelCaptureKeyUpAndDowns()
TInt32 handle2; // for CancelCaptureKey()
char *name;
};
//**********************************
//CPicoServServer
//**********************************
//The server class; an active object.
//Contains an instance of RServer; a handle to the kernel server representation which is used
//to receive messages.
class CPicoServServer : public CServer
{
public:
enum {EPriority=950};
public:
static void New();
virtual CSharableSession *NewSessionL(const TVersion &aVersion) const;
static TInt ThreadFunction(TAny* aStarted);
protected:
CPicoServServer(TInt aPriority);
private:
TInt iActive;
};
//**********************************
//CPicoServSession
//**********************************
//This class represents a session in the server.
//CSession::Client() returns the client thread.
//Functions are provided to respond appropriately to client messages.
class CPicoServSession : public CSession
{
public:
// construct/destruct
CPicoServSession(RThread &aClient, CPicoServServer * aServer);
static CPicoServSession* NewL(RThread &aClient, CPicoServServer * aServer);
//service request
virtual void ServiceL(const RMessage &aMessage);
void DispatchMessageL(const RMessage &aMessage);
// services available
void loadROM();
void changeConfig();
void sendConfig();
void sendDebug();
protected:
// panic the client
void PanicClient(TInt aPanic) const;
// safewrite between client and server
void Write(const TAny* aPtr,const TDesC8& aDes,TInt anOffset=0);
private:
//CPicoServServer *iPicoSvr;
unsigned char *rom_data;
};
//**********************************
//global functions
//**********************************
// function to panic the server
GLREF_C void PanicServer(TPicoServPanic aPanic);
int saveLoadGame(int load, int sram=0);
#endif // __SIMPLESERVER_H

View file

@ -1,24 +0,0 @@
#{"PicodriveN"},(0x1000C193),0,93,0
;
; For the UIQ?
(0x101F617B), 2, 0, 0, {"UIQ20ProductID"}
;
; PicodriveN (Frontend)
;
"..\..\..\..\..\epoc32\release\armi\urel\PicodriveN.app"-"!:\system\apps\PicodriveN\PicodriveN.app"
"..\..\..\..\..\epoc32\data\z\system\apps\PicodriveN\PicodriveN.rsc"-"!:\system\apps\PicodriveN\PicodriveN.rsc"
"..\..\..\..\..\epoc32\data\z\system\apps\PicodriveN\PicodriveN.aif"-"!:\system\apps\PicodriveN\PicodriveN.aif"
"..\audio\audio_mediaserver.dll"-"!:\system\apps\PicodriveN\audio_mediaserver.dll"
"..\audio\audio_motorola.dll"-"!:\system\apps\PicodriveN\audio_motorola.dll"
;
; Picosmall
;
"..\PICOSMALL.EXE"-"!:\system\apps\PicodriveN\PICOSMALL.EXE"
;
; Text to show during installation, not copied to destination
;
".\install.txt"-"!:\system\apps\PicodriveN\install.txt",FILETEXT

View file

@ -1,16 +0,0 @@
Be sure to configure keys before loading your first ROM, because there is no default config. You need to configure 'pause emu' function to exit game.
Key configuration tutorial:
http://notaz.atspace.com/pico_tut/
You can also hold power button to exit (PXXX only).
(Motorola users, try the 'end' button).
Some quick sound related notes:
* You must use auto frameskip or you will get stuttering sound.
* Sound needs a lot of CPU power, so it is best to use "fit 0" or "fit 180" display modes and to exit all other apps.
* if you change sound settings AFTER loading a ROM, you may need to reset game to get sound (this depends on a ROM itself).
Enabling Z80 in sound settings will improve compatibility (you don't have to enable anything else, only Z80), because some games need it to run. But it slows emulation down, so turn it off if the game doesn't need it.
See readme for more details.

View file

@ -1,347 +0,0 @@
About
-----
PicodriveN is another port of PicoDrive, Dave's Megadrive / Genesis
emulator for Pocket PC. This version is based on PicoDrive 0.030 and is
made for Symbian UIQ devices. It is alternative version to another port by
AnotherGuest / Someone and is not based on it (so it has a little
different name). It also has full sound support (starting
from version 0.70) .
Features
--------
* Good compatibility (> 90%)
* Improved Cyclone 68000 core.
* Zipped ROMs and savestates.
* SRAM support, including serial SRAM.
* Game screen rotation with many render modes (like 'centered' and 'fit').
* Selectable frameskip.
* Configurable keys and touchpad.
* Flip-closed mode for SE phones.
* Full sound support.
Problems / limitations
----------------------
* 32x, Sega CD, SVP are not emulated.
* Various VDP quirks (window bug, scroll size 2, etc.) are not emulated,
as very few games use this.
* Some games don't work or have glitches because of inaccurate sync.
Configuration
-------------
1. Keys:
If it looks confusing to you, check this tutorial first:
http://notaz.atspace.com/pico_tut/
There are no default settings.
When you start key configuration mode, black screen with dark-red squares will
appear. Also there will be little 'control' on the right with the function
name in it, and arrows on the corners of it. You can tap on these corners to
select a function. You can also tap on these squares to bind that function to
them. This way you can associate touchpad areas with game-controls or functions.
I also made a small square in every corner of the screen to be used as a virtual
button for some function, like save state. You can bind it as you like. To
bind phone buttons, simply select the function you need, and press a button
you want. To unbind any key or touchpad area, simply push or tap it again.
To configure flip-closed mode, enter configuration mode and close flip.
When finished, select 'done' and press any key. You can also hold 'Power'
button for a while to exit (seems to work on PXXX only).
You need to bind 'pause emu' function to be able exit game when ROM is loaded.
You can also exit game by holding 'power' button (possibly 'end' for motorola
users (?)).
2. Main Settings:
Here you can set the orientation of screen and the drawing mode. The "fit"
option will scale the image so it fully fits in the screen, but some detail
will be lost. "center" displays the game at the center of the screen, but
non-fitting parts are not visible then (better for RPG games with lots of
text, which becomes unreadable in 'fit' mode). "fit2" was meant for Pxxx FC
gaming and will always use 208x146 for P800 and 208x208 for all other phones.
"Fast renderer" enables faster rendering method, but it works only with some
games (some other have serious glitches or even hang).
"Accurate timing" is needed for some games to run (like Red Zone). It should
be kept off for all other games, because it slows emulation down. Some games
also need this option for proper sound, so enable this if game has any
glitches.
"Accurate sprites" fixes sprite priority problems, for example if game
character is in front of or behind some object it should not be, this option
should fix it. This option does not work in "Fast renderer" mode.
"Show FPS" shows game frames per second in format XX/YY, where XX is the
number of frames shown per previous second, and YY is the number of frames
emulated, but not necessarily shown. By calculating YY-XX you get the number
of skipped frames per second.
3. Sound settings:
Sound emulation is very picky on CPU power (in most cases sound alone uses
more CPU power than everything else altogether), but it is still possible to
play some games. When using sound, the recommended display modes are "fit 0"
and "fit 180", because these are the fastest ones. Also try "Alternative
renderer", but it might cause graphical glitches. You must use auto frameskip
when using sound, or else you will get stuttering sound. Also, it is
recommended to exit all other non-vital apps (you can use SMan for this),
disable bluetooth and any other devices your phone may have. I also noticed
that simply connecting the phone battery charger strangely slows everything
down.
"Enable sound" tries to enable sound output on your device, but that alone is
not enough to get sound. You need to enable the sound chips below:
"Z80" is secondary CPU in genesis and is mostly used to control the other 2
sound chips. So if you disable Z80, sound will be lost in most games, with
some exceptions like Sonic1. It is possible to use Z80 for other things,
some games do that and Z80 must be enabled to run them at all.
"YM2612" is a fairly complex Frequency Modulation (FM) sound synthesis chip.
It was the main sound output device in genesis and is horrible CPU hog when
is tried to be emulated in software. Disabling it gives large speed
improvement, but most of the sound is lost.
"SN76496" is programmable sound generator (PSG) chip, used for various sound
effects and music elements.
The lowest setting is audio quality setting, which should be left set to
"8000Hz mono", because other choces slow everything down terribly and
are left for testing and possibly for use in other ports to faster future
devices with faster CPUs.
Note: if you change sound settings AFTER loading a ROM, you may need to reset
game to get sound. This is because most games initialize sound chips on
startup, and this data is lost when sound chips are being enabled/disabled.
4. Misc:
"6 button pad" will enable 6 button gamepad emulation and will add additional
X, Y, Z and MODE actions to key configuration.
Note: if you enable this, games may detect that and use different button
configuration, for example A ("high punch") will change to "low punch" in
Mortal Kombat and you will need to bind X for "high punch".
"gzip save states" enables gzip (similar to ordinary zip, but a little
different) compression on your save states to save space. The compression
ratio is 50-90%, so it's worth to enable this.
"Use SRAM saves" option enables emulation of batery-backed save RAM some game
cartridges had. RPG games used it alot, but there were some others too, like
Sonic 3. If this is enabled, <ROMname>.srm files are generated when you exit
the emulator or load another ROM. Format is compatible with other popular
emulators (like Gens and Fusion).
5. Frameskip:
"Auto" option tries to run the game in it's original speed by skipping next
frame if the previous was rendered too slow.
"0" displays every frame, thus game runs very slow.
"1" skips every other frame. Use this for a game which is smoother, but a bit
too slow (actually depends on display mode you use).
"2" also makes the game smoother, but it will be too fast in most areas.
"4","8" is way too fast and is useful for skiping intros, etc.
Credits
-------
This emulator uses code from these people/projects:
Dave
Cyclone 68000 core, Pico emulation library
Homepage: http://www.finalburn.com/
E-mail: david(atsymbol)finalburn.com
notaz
UIQ port, Cyclone 68000 hacks, some additional coding (see changelog).
Homepage: http://notaz.atspace.com/
E-mail: notasas(atsymbol)gmail.com
Reesy & FluBBa
DrZ80, the Z80 emulator written in ARM assembly.
Homepage: http://reesy.gp32x.de/
E-mail: drsms_reesy(atsymbol)yahoo.co.uk
Tatsuyuki Satoh, Jarek Burczynski, MultiArcadeMachineEmulator development
software implementation of Yamaha FM sound generator
MultiArcadeMachineEmulator (MAME) development
Texas Instruments SN76489 / SN76496 programmable tone /noise generator
Homepage: http://www.mame.net/
Additional thanks
-----------------
* Peter van Sebille for ECompXL and his various open-source Symbian projects
to learn from.
* Steve Fischer for his open-source Motorola projects.
* Charles MacDonald (http://cgfm2.emuviews.com/) for old but still very useful
info about genesis hardware.
* Stéphane Dallongeville for creating Gens and making it open-source.
* Steve Snake for all that he has done for Genesis emulation scene.
* Bart Trzynadlowski for his SSFII and 68000 docs.
* Haze for his research (http://haze.mameworld.info).
* The development team behind "Symbian GCC Improvement Project"
(http://www.inf.u-szeged.hu/symbian-gcc/) for their updated compile tools.
* Mark and Jean-loup for zlib library.
* Reesy for also finding some Cyclone bugs.
* Inder for the icons.
Changelog
---------
0.94
* Improved interrupt timing, Mazin Saga and Burning Force now works.
* Rewritten renderer code to better suit gp2x, should be faster on other
ports too.
+ Added support for banking used by 12-in-1 and 4-in-1 ROMs (thanks Haze).
+ Added some protection device faking, used by some unlicensed games like
Super Bubble Bobble, King of Fighters, Elf Wor, ...
+ Added primitive Virtua Racing SVP faking, so menus can be seen now.
0.93
* Fixed a problem with P900/P910 key configuration in FC mode.
* Improved shadow/hilight mode emulation. Still not perfect, but should be
enough for most games.
+ Save state slots added.
+ Region selector added.
0.92
VDP changes:
* VDP emulation is now more accurate (fixes flickering in Chase HQ II,
Super Hang-On and some other problems in other games).
* HV counter emulation is now much more accurate. Fixes the Asterix games,
line in Road Rash 3, etc.
* Minnor sprite and layer scroll masking bugs fixed.
+ Added partial interlace mode renderer (Sonic 2 vs mode)
* Fixed a crash in both renderers when certain size window layers were used.
+ Added emulation of shadow/hilight operator sprites. Other shadow/hilight
effects are still unemulated.
+ Sprite emulation is more accurate, sprite limit is emulated.
+ Added "accurate sprites" option, which always draws sprites in correct
order and emulates sprite collision bit, but is significantly slower.
Emulation changes:
* Improved interrupt handling, added deferred interrupt emulation
(Lemmings, etc).
+ Added serial EEPROM SRAM support (Wonder Boy in Monster World,
Megaman - The Wily Wars and many EA sports games like NBA Jam).
+ Implemented ROM banking for Super Street Fighter II - The New Challengers
* Updated to the latest version of DrZ80 core, integrated memory handlers
in it for better performance. A noticeable performance increase, but save
states may not work from the previous version (you can only use them with
sound disabled in that case).
+ SRAM word read handler was using incorrect byte order, fixed.
Changes in Cyclone 0.0086:
+ Added missing CHK opcode handler (used by SeaQuest DSV).
+ Added missing TAS opcode handler (Gargoyles,Bubba N Stix,...). As in real genesis,
memory write-back phase is ignored (but can be enabled in config.h if needed).
+ Added missing NBCD and TRAPV opcode handlers.
+ Added missing addressing mode for CMP/EOR.
+ Added some minor optimizations.
- Removed 216 handlers for 2927 opcodes which were generated for invalid addressing modes.
+ Fixed flags for ASL, NEG, NEGX, DIVU, ADDX, SUBX, ROXR.
+ Bugs fixed in MOVEP, LINK, ADDQ, DIVS handlers.
* Undocumented flags for CHK, ABCD, SBCD and NBCD are now emulated the same way as in Musashi.
+ Added Uninitialized Interrupt emulation.
+ Altered timing for about half of opcodes to match Musashi's.
0.80
* Nearly all VDP code was rewritten in ARM asm. Gives ~10-25% performance
increase (depends on game).
* Optimized 32-column renderer not to render tiles offscreen, games which
use 32-column display (like Shining Force) run ~50% faster.
+ Added new "Alternative renderer", which gives another ~30-45% performance
increase (in addition to mentioned above), but works only with some games,
because it is missing some features (it uses tile-based renderering
instead of default line-based and disables H-ints).
+ Added "fit2" display mode for all FC gamers. It always uses 208x146 for
P800 and 208x208 for all other phones.
+ Added volume control for Motorolas (experimental).
VDP changes:
+ Added support for vertical window (used by Vapor Trail, Mercs, GRIND
Stormer and others).
+ Added sprite masking (hiding), adds some speed.
+ Added preliminary H counter emulation. Comix Zone and Sonic 3D Blast
special stage are now playable.
+ Added column based vertical scrolling (Gunstar Heroes battleship level,
Sonic and Knuckles lava boss, etc).
Emulation changes:
+ Re-added and improved Z80 faking when Z80 is disabled. Many games now can
be played without enabling Z80 (Lost Vikings, Syndicate, etc), but some
still need it (International Superstar Soccer Deluxe).
* Improved ym2612 timers, Outrun music plays at correct speed, voices in
Earthworm Jim play better, more games play sound.
* I/O registers now remember their values (needed for Pirates! Gold)
+ Added support for 6 button pad.
Changes in Cyclone 0.0083wip:
+ Added missing CHK opcode (used by SeaQuest DSV).
+ Added missing TAS opcode (Gargoyles). As in real genesis, write-back phase
is ignored (but is enabled for other systems).
Backported stuff from Snes9x:
* Fixed Pxxx jog up/down which were not working in game.
+ Added an option to gzip save states to save space.
+ The emulator now pauses whenever it is loosing focus, so it will now pause
when alarm/ponecall/battery low/... windows come up.
- Removed 'pause on phonecall' feature, as it is no longer needed.
+ Video fix for asian A1000s.
0.70
* Started using tools from "Symbian GCC Improvement Project", which give
considerable speed increase (~4fps in "center 90" mode).
* Rewrote some drawing routines in ARM assembly (gives ~6 more fps in
"center 90" mode).
* Minor improvement to 0 and 180 "fit" modes. Now they look slightly better
and are faster.
* Minor stability improvements (emulator is less likely to crash).
+ Added some background for OSD text for better readability.
+ Added Pal/NTSC detection. This is needed for proper sound speed.
+ Implemented Reesy's DrZ80 Z80 emu. Made some changes to it with hope to make
it faster.
+ Implemented ym2612 emu from the MAME project. Runs well but sometimes sounds
a bit weird. Could be a little faster, so made some changes too.
+ Implemented SN76489 emu from the MAME project.
+ Added two separate sound output methods (mediaserver and cmaudiofb) with
autodetection (needs testing).
* Fixed VDP DMA fill emulation (as described in Charles MacDonald's docs),
fixes Contra and some other games.
0.301
Launcher:
* Launcher now starts emulation process from current directory,
not from hardcoded paths.
* Improved 'pause on call' feature, should hopefully work with Motorola phones.
0.30
Initial release.
Disclaimer
----------
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.

View file

@ -1,24 +0,0 @@
// audio interface, used in picodriveN
#ifndef __AUDIO_H
#define __AUDIO_H
#include <e32std.h>
class IGameAudio : public CBase
{
public:
virtual TInt16 *NextFrameL() = 0;
virtual TInt16 *DupeFrameL(TInt &aUnderflowed) = 0;
virtual TInt16 *ResumeL() = 0;
virtual void Pause() = 0;
virtual void ChangeVolume(TInt aUp) = 0; // for Motorolas (experimental)
};
// our audio object maker type
typedef IGameAudio *(*_gameAudioNew)(TInt aRate, TBool aStereo, TInt aPcmFrames, TInt aBufferedFrames);
#endif /* __AUDIO_H */

View file

@ -1,402 +0,0 @@
# CWD \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\
# MMPFile \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER.MMP
# Target AUDIO_MEDIASERVER.DLL
# TargetType DLL
# BasicTargetType DLL
# MakefileType GNU
ERASE = @erase 2>>nul
# EPOC DEFINITIONS
EPOCBLD = ..\..\..\..\EPOC32\BUILD\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER\ARMI
EPOCTRG = ..\..\..\..\EPOC32\RELEASE\ARMI
EPOCLIB = ..\..\..\..\EPOC32\RELEASE\ARMI
EPOCLINK = ..\..\..\..\EPOC32\RELEASE\ARMI
EPOCSTATLINK = ..\..\..\..\EPOC32\RELEASE\ARMI
EPOCASSPLINK = ..\..\..\..\EPOC32\RELEASE\MARM
EPOCDATA = \DEV\UIQ21\EPOC32\DATA
EPOCINC = \DEV\UIQ21\EPOC32\INCLUDE
TRGDIR =
DATADIR = Z\SYSTEM\DATA
EPOCBLDUREL = $(EPOCBLD)\UREL
EPOCTRGUREL = $(EPOCTRG)\UREL
EPOCLIBUREL = $(EPOCLIB)\UREL
EPOCLINKUREL = $(EPOCLINK)\UREL
EPOCSTATLINKUREL = $(EPOCSTATLINK)\UREL
EPOCASSPLINKUREL = $(EPOCASSPLINK)\UREL
EPOCBLDUDEB = $(EPOCBLD)\UDEB
EPOCTRGUDEB = $(EPOCTRG)\UDEB
EPOCLIBUDEB = $(EPOCLIB)\UREL
EPOCLINKUDEB = $(EPOCLINK)\UREL
EPOCSTATLINKUDEB = $(EPOCSTATLINK)\UDEB
EPOCASSPLINKUDEB = $(EPOCASSPLINK)\UREL
# EPOC PSEUDOTARGETS
UREL : MAKEWORKUREL RESOURCEUREL
UDEB : MAKEWORKUDEB RESOURCEUDEB
ALL : UREL UDEB
CLEAN CLEANALL : CLEANBUILD CLEANRELEASE CLEANLIBRARY
WHAT WHATALL : WHATUREL WHATUDEB
RESOURCE RESOURCEALL : RESOURCEUREL RESOURCEUDEB
CLEANBUILD CLEANBUILDALL : CLEANBUILDUREL CLEANBUILDUDEB
CLEANRELEASE CLEANRELEASEALL : CLEANRELEASEUREL CLEANRELEASEUDEB
MAKEWORK MAKEWORKALL : MAKEWORKUREL MAKEWORKUDEB
LISTING LISTINGALL : LISTINGUREL LISTINGUDEB
MAKEWORK : MAKEWORKLIBRARY
RESOURCEUREL RESOURCEUDEB : GENERIC_RESOURCE
# must set both PATH and Path to make it work correctly
Path:=X:\DEV\UIQ21\EPOC32\gcc\bin;$(Path)
PATH:=$(Path)
INCDIR = -I "." -I "..\.." -I "..\..\..\..\EPOC32\INCLUDE"
GCCFLAGS=-march=armv4t -mthumb-interwork \
-pipe -c -nostdinc -Wall -Wno-ctor-dtor-privacy -Wno-unknown-pragmas
GCCDEFS = -D__SYMBIAN32__ -D__GCC32__ -D__EPOC32__ -D__MARM__ -D__MARM_ARMI__ -D__DLL__ $(USERDEFS)
GCCUREL = gcc -s -fomit-frame-pointer -O $(GCCFLAGS) -DNDEBUG -D_UNICODE $(GCCDEFS)
GCCUDEB = gcc -g -O $(GCCFLAGS) -D_DEBUG -D_UNICODE $(GCCDEFS)
UREL : \
$(EPOCTRGUREL)\AUDIO_MEDIASERVER.DLL \
LIBRARY
UDEB : \
$(EPOCTRGUDEB)\AUDIO_MEDIASERVER.DLL \
LIBRARY
RESOURCEUREL : MAKEWORKUREL
RESOURCEUDEB : MAKEWORKUDEB
LIBRARY : MAKEWORKLIBRARY $(EPOCLIB)\UREL\AUDIO_MEDIASERVER.LIB \DEV\UIQ21\EPOC32\RELEASE\ARM4\UREL\AUDIO_MEDIASERVER.LIB \DEV\UIQ21\EPOC32\RELEASE\THUMB\UREL\AUDIO_MEDIASERVER.LIB
# REAL TARGET - LIBRARY
$(EPOCLIB)\UREL\AUDIO_MEDIASERVER.LIB : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER.DEF
dlltool -m arm_interwork --output-lib "$(EPOCLIB)\UREL\AUDIO_MEDIASERVER.LIB" \
--def ".\AUDIO_MEDIASERVER.DEF" \
--dllname "AUDIO_MEDIASERVER[1000c196].DLL"
\DEV\UIQ21\EPOC32\RELEASE\ARM4\UREL\AUDIO_MEDIASERVER.LIB : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER.DEF
dlltool -m arm --output-lib "..\..\..\..\EPOC32\RELEASE\ARM4\UREL\AUDIO_MEDIASERVER.LIB" \
--def ".\AUDIO_MEDIASERVER.DEF" \
--dllname "AUDIO_MEDIASERVER[1000c196].DLL"
\DEV\UIQ21\EPOC32\RELEASE\THUMB\UREL\AUDIO_MEDIASERVER.LIB : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER.DEF
dlltool -m thumb --output-lib "..\..\..\..\EPOC32\RELEASE\THUMB\UREL\AUDIO_MEDIASERVER.LIB" \
--def ".\AUDIO_MEDIASERVER.DEF" \
--dllname "AUDIO_MEDIASERVER[1000c196].DLL"
FREEZE :
perl -S efreeze.pl "\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER.DEF" "$(EPOCBLD)\AUDIO_MEDIASERVER.def"
CLEANLIBRARY :
-$(ERASE) "$(EPOCLIB)\UREL\AUDIO_MEDIASERVER.LIB"
-$(ERASE) "\DEV\UIQ21\EPOC32\RELEASE\ARM4\UREL\AUDIO_MEDIASERVER.LIB"
-$(ERASE) "\DEV\UIQ21\EPOC32\RELEASE\THUMB\UREL\AUDIO_MEDIASERVER.LIB"
GENERIC_RESOURCE : GENERIC_MAKEWORK
# REAL TARGET - BUILD VARIANT UREL
WHATUREL : WHATGENERIC
CLEANUREL : CLEANBUILDUREL CLEANRELEASEUREL
CLEANBUILDUREL :
@perl -S ermdir.pl "$(EPOCBLDUREL)"
CLEANRELEASEUREL : CLEANGENERIC
UREL_RELEASEABLES1= \
\DEV\UIQ21\EPOC32\RELEASE\ARM4\UREL\AUDIO_MEDIASERVER.LIB \
\DEV\UIQ21\EPOC32\RELEASE\ARMI\UREL\AUDIO_MEDIASERVER.DLL \
\DEV\UIQ21\EPOC32\RELEASE\ARMI\UREL\AUDIO_MEDIASERVER.DLL.MAP \
\DEV\UIQ21\EPOC32\RELEASE\ARMI\UREL\AUDIO_MEDIASERVER.LIB \
\DEV\UIQ21\EPOC32\RELEASE\THUMB\UREL\AUDIO_MEDIASERVER.LIB
WHATUREL:
@echo $(UREL_RELEASEABLES1)
CLEANRELEASEUREL:
-$(ERASE) $(UREL_RELEASEABLES1)
LISTINGUREL : MAKEWORKUREL \
LISTINGURELAUDIO_MEDIASERVER \
LISTINGURELPOLLEDAS
LIBSUREL= \
$(EPOCSTATLINKUREL)\EDLLSTUB.LIB \
$(EPOCSTATLINKUREL)\EGCC.LIB \
$(EPOCLINKUREL)\EUSER.LIB \
$(EPOCLINKUREL)\MEDIACLIENTAUDIOSTREAM.LIB \
$(EPOCLINKUREL)\MEDIACLIENT.LIB
$(EPOCTRGUREL)\AUDIO_MEDIASERVER.DLL : $(EPOCBLDUREL)\AUDIO_MEDIASERVER.in \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER.DEF $(EPOCSTATLINKUREL)\EDLL.LIB $(LIBSUREL)
dlltool -m arm_interwork --output-def "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.inf" "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.in"
perl -S makedef.pl -Deffile "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.inf" -Frzfile "\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER.DEF" "$(EPOCBLD)\AUDIO_MEDIASERVER.def"
-$(ERASE) "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.inf"
dlltool -m arm_interwork --def "$(EPOCBLD)\AUDIO_MEDIASERVER.def" \
--output-exp "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.exp" \
--dllname "AUDIO_MEDIASERVER[1000c196].DLL"
ld -s -e _E32Dll -u _E32Dll "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.exp" --dll \
--base-file "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.bas" -o "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.DLL" \
"$(EPOCSTATLINKUREL)\EDLL.LIB" --whole-archive "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.in" \
--no-whole-archive $(LIBSUREL) $(USERLDFLAGS)
-$(ERASE) "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.exp"
-$(ERASE) "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.DLL"
dlltool -m arm_interwork \
--def "$(EPOCBLD)\AUDIO_MEDIASERVER.def" \
--dllname "AUDIO_MEDIASERVER[1000c196].DLL" \
--base-file "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.bas" \
--output-exp "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.exp"
-$(ERASE) "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.bas"
ld -s -e _E32Dll -u _E32Dll --dll \
"$(EPOCBLDUREL)\AUDIO_MEDIASERVER.exp" \
-Map "$(EPOCTRGUREL)\AUDIO_MEDIASERVER.DLL.map" -o "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.DLL" \
"$(EPOCSTATLINKUREL)\EDLL.LIB" --whole-archive "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.in" \
--no-whole-archive $(LIBSUREL) $(USERLDFLAGS)
-$(ERASE) "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.exp"
petran "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.DLL" "$@" \
-nocall -uid1 0x10000079 -uid2 0x100039ce -uid3 0x1000c196
-$(ERASE) "$(EPOCBLDUREL)\AUDIO_MEDIASERVER.DLL"
OBJECTSUREL= \
$(EPOCBLDUREL)\AUDIO_MEDIASERVER.o \
$(EPOCBLDUREL)\POLLEDAS.o
$(EPOCBLDUREL)\AUDIO_MEDIASERVER.in : $(OBJECTSUREL)
if exist "$@" del "$@"
ar cr $@ $^
# REAL TARGET - BUILD VARIANT UDEB
WHATUDEB : WHATGENERIC
CLEANUDEB : CLEANBUILDUDEB CLEANRELEASEUDEB
CLEANBUILDUDEB :
@perl -S ermdir.pl "$(EPOCBLDUDEB)"
CLEANRELEASEUDEB : CLEANGENERIC
UDEB_RELEASEABLES1= \
\DEV\UIQ21\EPOC32\RELEASE\ARM4\UREL\AUDIO_MEDIASERVER.LIB \
\DEV\UIQ21\EPOC32\RELEASE\ARMI\UDEB\AUDIO_MEDIASERVER.DLL \
\DEV\UIQ21\EPOC32\RELEASE\ARMI\UDEB\AUDIO_MEDIASERVER.DLL.MAP \
\DEV\UIQ21\EPOC32\RELEASE\ARMI\UREL\AUDIO_MEDIASERVER.LIB \
\DEV\UIQ21\EPOC32\RELEASE\THUMB\UREL\AUDIO_MEDIASERVER.LIB
WHATUDEB:
@echo $(UDEB_RELEASEABLES1)
CLEANRELEASEUDEB:
-$(ERASE) $(UDEB_RELEASEABLES1)
LISTINGUDEB : MAKEWORKUDEB \
LISTINGUDEBAUDIO_MEDIASERVER \
LISTINGUDEBPOLLEDAS
LIBSUDEB= \
$(EPOCSTATLINKUDEB)\EDLLSTUB.LIB \
$(EPOCSTATLINKUDEB)\EGCC.LIB \
$(EPOCLINKUDEB)\EUSER.LIB \
$(EPOCLINKUDEB)\MEDIACLIENTAUDIOSTREAM.LIB \
$(EPOCLINKUDEB)\MEDIACLIENT.LIB
$(EPOCTRGUDEB)\AUDIO_MEDIASERVER.DLL : $(EPOCBLDUDEB)\AUDIO_MEDIASERVER.in \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER.DEF $(EPOCSTATLINKUDEB)\EDLL.LIB $(LIBSUDEB)
dlltool -m arm_interwork --output-def "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.inf" "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.in"
perl -S makedef.pl -Deffile "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.inf" -Frzfile "\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER.DEF" "$(EPOCBLD)\AUDIO_MEDIASERVER.def"
-$(ERASE) "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.inf"
dlltool -m arm_interwork --def "$(EPOCBLD)\AUDIO_MEDIASERVER.def" \
--output-exp "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.exp" \
--dllname "AUDIO_MEDIASERVER[1000c196].DLL"
ld -s -e _E32Dll -u _E32Dll "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.exp" --dll \
--base-file "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.bas" -o "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.DLL" \
"$(EPOCSTATLINKUDEB)\EDLL.LIB" --whole-archive "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.in" \
--no-whole-archive $(LIBSUDEB) $(USERLDFLAGS)
-$(ERASE) "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.exp"
-$(ERASE) "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.DLL"
dlltool -m arm_interwork \
--def "$(EPOCBLD)\AUDIO_MEDIASERVER.def" \
--dllname "AUDIO_MEDIASERVER[1000c196].DLL" \
--base-file "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.bas" \
--output-exp "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.exp"
-$(ERASE) "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.bas"
ld -e _E32Dll -u _E32Dll --dll \
"$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.exp" \
-Map "$(EPOCTRGUDEB)\AUDIO_MEDIASERVER.DLL.map" -o "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.DLL" \
"$(EPOCSTATLINKUDEB)\EDLL.LIB" --whole-archive "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.in" \
--no-whole-archive $(LIBSUDEB) $(USERLDFLAGS)
-$(ERASE) "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.exp"
objcopy -X "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.DLL" "$(EPOCTRGUDEB)\AUDIO_MEDIASERVER.sym"
petran "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.DLL" "$@" \
-nocall -uid1 0x10000079 -uid2 0x100039ce -uid3 0x1000c196
-$(ERASE) "$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.DLL"
OBJECTSUDEB= \
$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.o \
$(EPOCBLDUDEB)\POLLEDAS.o
$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.in : $(OBJECTSUDEB)
if exist "$@" del "$@"
ar cr $@ $^
# SOURCES
# Source AUDIO_MEDIASERVER.CPP
$(EPOCBLDUREL)\AUDIO_MEDIASERVER.lis $(EPOCBLDUREL)\AUDIO_MEDIASERVER.o \
$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.lis $(EPOCBLDUDEB)\AUDIO_MEDIASERVER.o \
: \
\DEV\UIQ21\EPOC32\INCLUDE\E32BASE.H \
\DEV\UIQ21\EPOC32\INCLUDE\E32BASE.INL \
\DEV\UIQ21\EPOC32\INCLUDE\E32DEF.H \
\DEV\UIQ21\EPOC32\INCLUDE\E32DES16.H \
\DEV\UIQ21\EPOC32\INCLUDE\E32DES8.H \
\DEV\UIQ21\EPOC32\INCLUDE\E32HAL.H \
\DEV\UIQ21\EPOC32\INCLUDE\E32KEYS.H \
\DEV\UIQ21\EPOC32\INCLUDE\E32PCCD.H \
\DEV\UIQ21\EPOC32\INCLUDE\E32STD.H \
\DEV\UIQ21\EPOC32\INCLUDE\E32STD.INL \
\DEV\UIQ21\EPOC32\INCLUDE\E32SVR.H \
\DEV\UIQ21\EPOC32\INCLUDE\MDAAUDIOOUTPUTSTREAM.H \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\CLIENT\BASE.H \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\CLIENT\BASE.INL \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\CLIENT\CONTROLLER.H \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\CLIENT\PORT.H \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\CLIENT\UTILITY.H \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\COMMON\AUDIO.H \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\COMMON\AUDIO.HRH \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\COMMON\AUDIOSTREAM.HRH \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\COMMON\BASE.H \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\COMMON\BASE.H \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\COMMON\BASE.HRH \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\COMMON\BASE.INL \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\COMMON\CONTROLLER.H \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\COMMON\CONTROLLER.H \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\COMMON\CONTROLLER.HRH \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\COMMON\PORT.H \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\COMMON\PORT.HRH \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\COMMON\RESOURCE.H \
\DEV\UIQ21\EPOC32\INCLUDE\MDA\COMMON\RESOURCE.HRH \
\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO.H \
\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER.H \
\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\POLLEDAS.H
$(EPOCBLDUREL)\AUDIO_MEDIASERVER.o : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\Audio_mediaserver.cpp
$(GCCUREL) -I "." $(INCDIR) -o $@ ".\Audio_mediaserver.cpp"
LISTINGURELAUDIO_MEDIASERVER : $(EPOCBLDUREL)\AUDIO_MEDIASERVER.lis
perl -S ecopyfile.pl $? \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER.lst.ARMI
$(EPOCBLDUREL)\AUDIO_MEDIASERVER.lis : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\Audio_mediaserver.cpp
$(GCCUREL) -Wa,-adln -I "." $(INCDIR) -o nul: ".\Audio_mediaserver.cpp" > $@
$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.o : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\Audio_mediaserver.cpp
$(GCCUDEB) -I "." $(INCDIR) -o $@ ".\Audio_mediaserver.cpp"
LISTINGUDEBAUDIO_MEDIASERVER : $(EPOCBLDUDEB)\AUDIO_MEDIASERVER.lis
perl -S ecopyfile.pl $? \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER.lst.ARMI
$(EPOCBLDUDEB)\AUDIO_MEDIASERVER.lis : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\Audio_mediaserver.cpp
$(GCCUDEB) -Wa,-adln -I "." $(INCDIR) -o nul: ".\Audio_mediaserver.cpp" > $@
# Source POLLEDAS.CPP
$(EPOCBLDUREL)\POLLEDAS.lis $(EPOCBLDUREL)\POLLEDAS.o \
$(EPOCBLDUDEB)\POLLEDAS.lis $(EPOCBLDUDEB)\POLLEDAS.o \
: \
\DEV\UIQ21\EPOC32\INCLUDE\E32DEF.H \
\DEV\UIQ21\EPOC32\INCLUDE\E32DES16.H \
\DEV\UIQ21\EPOC32\INCLUDE\E32DES8.H \
\DEV\UIQ21\EPOC32\INCLUDE\E32STD.H \
\DEV\UIQ21\EPOC32\INCLUDE\E32STD.INL \
\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\POLLEDAS.H
$(EPOCBLDUREL)\POLLEDAS.o : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\Polledas.cpp
$(GCCUREL) -I "." $(INCDIR) -o $@ ".\Polledas.cpp"
LISTINGURELPOLLEDAS : $(EPOCBLDUREL)\POLLEDAS.lis
perl -S ecopyfile.pl $? \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\POLLEDAS.lst.ARMI
$(EPOCBLDUREL)\POLLEDAS.lis : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\Polledas.cpp
$(GCCUREL) -Wa,-adln -I "." $(INCDIR) -o nul: ".\Polledas.cpp" > $@
$(EPOCBLDUDEB)\POLLEDAS.o : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\Polledas.cpp
$(GCCUDEB) -I "." $(INCDIR) -o $@ ".\Polledas.cpp"
LISTINGUDEBPOLLEDAS : $(EPOCBLDUDEB)\POLLEDAS.lis
perl -S ecopyfile.pl $? \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\POLLEDAS.lst.ARMI
$(EPOCBLDUDEB)\POLLEDAS.lis : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\Polledas.cpp
$(GCCUDEB) -Wa,-adln -I "." $(INCDIR) -o nul: ".\Polledas.cpp" > $@
ROMFILE:
@echo file=\DEV\UIQ21\EPOC32\RELEASE\ARMI\##BUILD##\AUDIO_MEDIASERVER.DLL System\Libs\AUDIO_MEDIASERVER.DLL
WHATGENERIC CLEANGENERIC :
@rem none
# Rules to create all necessary directories
GENERIC_MAKEWORK : \
\DEV\UIQ21\EPOC32\BUILD\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER\ARMI
MAKEWORKLIBRARY : \
\DEV\UIQ21\EPOC32\RELEASE\ARM4\UREL \
\DEV\UIQ21\EPOC32\RELEASE\ARMI\UREL \
\DEV\UIQ21\EPOC32\RELEASE\THUMB\UREL
MAKEWORKUDEB : \
\DEV\UIQ21\EPOC32\BUILD\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER\ARMI\UDEB \
\DEV\UIQ21\EPOC32\RELEASE\ARMI\UDEB
MAKEWORKUREL : \
\DEV\UIQ21\EPOC32\BUILD\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER\ARMI\UREL \
\DEV\UIQ21\EPOC32\RELEASE\ARMI\UREL
\DEV\UIQ21\EPOC32\BUILD\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER\ARMI \
\DEV\UIQ21\EPOC32\BUILD\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER\ARMI\UDEB \
\DEV\UIQ21\EPOC32\BUILD\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MEDIASERVER\AUDIO_MEDIASERVER\ARMI\UREL \
\DEV\UIQ21\EPOC32\RELEASE\ARM4\UREL \
\DEV\UIQ21\EPOC32\RELEASE\ARMI\UDEB \
\DEV\UIQ21\EPOC32\RELEASE\ARMI\UREL \
\DEV\UIQ21\EPOC32\RELEASE\THUMB\UREL \
:
perl -S emkdir.pl $@

View file

@ -1,32 +0,0 @@
/*******************************************************************
*
* File: PolledAS.h
*
* Author: Peter van Sebille (peter@yipton.net)
*
* (c) Copyright 2001, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#ifndef __POLLED_AS_H
#define __POLLED_AS_H
class CPrivatePolledActiveScheduler;
class CPolledActiveScheduler : public CBase
{
public:
~CPolledActiveScheduler();
static CPolledActiveScheduler* NewL();
//static CPolledActiveScheduler* Instance();
void Schedule();
protected:
CPolledActiveScheduler(){};
void ConstructL();
CPrivatePolledActiveScheduler* iPrivatePolledActiveScheduler;
};
#endif /* __POLLED_AS_H */

View file

@ -1,321 +0,0 @@
/*******************************************************************
*
* File: Audio_mediaserver.cpp
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2001, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#include "audio_mediaserver.h"
//#define __DEBUG_PRINT_SND
#ifdef __DEBUG_PRINT_SND
#include <e32svr.h> // RDebug
#define DEBUGPRINT(x...) RDebug::Print(x)
#else
#define DEBUGPRINT(x...)
#endif
GLDEF_C TInt E32Dll(TDllReason)
{
return KErrNone;
}
/*******************************************
*
* CGameAudioMS
*
*******************************************/
CGameAudioMS::CGameAudioMS(TInt aRate, TBool aStereo, TInt aPcmFrames, TInt aBufferedFrames)
: iRate(aRate), iStereo(aStereo), iBufferedFrames(aBufferedFrames), iPcmFrames(aPcmFrames)
{
}
CGameAudioMS* CGameAudioMS::NewL(TInt aRate, TBool aStereo, TInt aPcmFrames, TInt aBufferedFrames)
{
DEBUGPRINT(_L("CGameAudioMS::NewL(%i, %i, %i, %i)"),aRate, aStereo, aPcmFrames, aBufferedFrames);
CGameAudioMS* self = new(ELeave) CGameAudioMS(aRate, aStereo, aPcmFrames, aBufferedFrames);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(); // self
return self;
}
CGameAudioMS::~CGameAudioMS()
{
DEBUGPRINT(_L("CGameAudioMS::~CGameAudioMS()"));
if(iMdaAudioOutputStream) {
iScheduler->Schedule(); // let it finish it's stuff
iMdaAudioOutputStream->Stop();
delete iMdaAudioOutputStream;
}
if(iServer) delete iServer;
for (TInt i=0 ; i<KSoundBuffers+1 ; i++)
delete iSoundBuffers[i];
// Polled AS
if(iScheduler) delete iScheduler;
}
void CGameAudioMS::ConstructL()
{
iServer = CMdaServer::NewL();
iScheduler = CPolledActiveScheduler::NewL();
switch(iRate) {
case 11025: iMdaAudioDataSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate11025Hz; break;
case 16000: iMdaAudioDataSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate16000Hz; break;
case 22050: iMdaAudioDataSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate22050Hz; break;
default: iMdaAudioDataSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate8000Hz; break;
}
iMdaAudioDataSettings.iChannels = (iStereo) ? TMdaAudioDataSettings::EChannelsStereo : TMdaAudioDataSettings::EChannelsMono;
iMdaAudioDataSettings.iCaps = TMdaAudioDataSettings::ESampleRateFixed | iMdaAudioDataSettings.iSampleRate;
iMdaAudioDataSettings.iFlags = TMdaAudioDataSettings::ENoNetworkRouting;
TInt bytesPerFrame = iStereo ? iPcmFrames << 2 : iPcmFrames << 1;
for (TInt i=0 ; i<KSoundBuffers ; i++)
{
iSoundBuffers[i] = HBufC8::NewL(bytesPerFrame * iBufferedFrames);
iSoundBuffers[i]->Des().FillZ (bytesPerFrame * iBufferedFrames);
}
// because feeding 2 buffers after an underflow is a little too much, but feeding 1 may be not enough,
// prepare this ~50ms empty buffer to additionaly feed after every underflow.
// Another strange thing here: if we try to make and odd-length sound buffer here,
// system then outputs horrible noise! (this happened on 22050 mono and when there
// were no parenthesis around iBufferedFrames / 4.
iSoundBuffers[KSoundBuffers] = HBufC8::NewL(bytesPerFrame * (iBufferedFrames / 4));
iSoundBuffers[KSoundBuffers]->Des().FillZ (bytesPerFrame * (iBufferedFrames / 4));
iCurrentBuffer = 0;
// here we actually test if we can create and open CMdaAudioOutputStream at all, but really create and use it later.
iMdaAudioOutputStream = CMdaAudioOutputStream::NewL(iListener, iServer);
if(iMdaAudioOutputStream) {
delete iMdaAudioOutputStream;
iMdaAudioOutputStream = 0;
}
}
/* currently unused
TInt CGameAudioMS::Write(TInt16* aBuffer, TInt aSize)
{
TInt byteSize = iStereo ? aSize << 2 : aSize << 1;
Mem::Copy(iCurrentPosition, aBuffer, byteSize);
iCurrentPosition += aSize;
if (++iFrameCount == iBufferedFrames)
{
WriteBlock();
}
CPolledActiveScheduler::Instance()->Schedule();
if(iListener.iUnderflowed) Underflowed(); // oh no, CMdaAudioOutputStream underflowed!
return aSize;
}
*/
// returns a pointer to buffer for next frame,
// to be used when iSoundBuffers are used directly
TInt16 *CGameAudioMS::NextFrameL()
{
iCurrentPosition += iPcmFrames << (iStereo?1:0);
if (++iFrameCount == iBufferedFrames)
{
WriteBlockL();
}
iScheduler->Schedule();
if(iListener.iUnderflowed) {
if(iListener.iUnderflowed > KMaxUnderflows) {
delete iMdaAudioOutputStream;
iMdaAudioOutputStream = 0;
return 0;
}
UnderflowedL(); // not again!
}
return iCurrentPosition;
}
TInt16 *CGameAudioMS::DupeFrameL(TInt &aUnderflowed)
{
TInt shorts = iStereo ? (iPcmFrames << 1) : iPcmFrames;
if(iFrameCount)
Mem::Copy(iCurrentPosition, iCurrentPosition-shorts, shorts<<1);
else {
TInt lastBuffer = iCurrentBuffer;
if(--lastBuffer < 0) lastBuffer = KSoundBuffers - 1;
Mem::Copy(iCurrentPosition, ((TInt16*) (iSoundBuffers[lastBuffer]->Ptr()))+shorts*(iBufferedFrames-1), shorts<<1);
}
iCurrentPosition += shorts;
if (++iFrameCount == iBufferedFrames)
{
WriteBlockL();
}
iScheduler->Schedule();
if((aUnderflowed = iListener.iUnderflowed)) { // not again!
if(iListener.iUnderflowed > KMaxUnderflows) {
delete iMdaAudioOutputStream;
iMdaAudioOutputStream = 0;
return 0;
}
UnderflowedL(); // not again!
}
return iCurrentPosition;
}
void CGameAudioMS::WriteBlockL()
{
iScheduler->Schedule();
// do not write until stream is open
if(!iListener.iIsOpen) WaitForOpenToCompleteL();
//if(!iListener.iHasCopied) WaitForCopyToCompleteL(); // almost never happens anyway and sometimes even deadlocks?
//iListener.iHasCopied = EFalse;
if(!iListener.iUnderflowed) {
// don't write if sound is lagging too much
if(iTime - iMdaAudioOutputStream->Position().Int64() <= TInt64(0, KMaxLag)) {
//RDebug::Print(_L("delta: %i"), iTime.Low() - iMdaAudioOutputStream->Position().Int64().Low());
iMdaAudioOutputStream->WriteL(*iSoundBuffers[iCurrentBuffer]);
iTime += KBlockTime;
}
}
iFrameCount = 0;
if (++iCurrentBuffer == KSoundBuffers)
iCurrentBuffer = 0;
iCurrentPosition = (TInt16*) iSoundBuffers[iCurrentBuffer]->Ptr();
}
void CGameAudioMS::Pause()
{
if(!iMdaAudioOutputStream) return;
iScheduler->Schedule(); // let it finish it's stuff
iMdaAudioOutputStream->Stop();
delete iMdaAudioOutputStream;
iMdaAudioOutputStream = 0;
}
// call this before doing any playback!
TInt16 *CGameAudioMS::ResumeL()
{
DEBUGPRINT(_L("CGameAudioMS::Resume()"));
iScheduler->Schedule();
// we act a bit strange here: simulate buffer underflow, which actually starts audio
iListener.iIsOpen = ETrue;
iListener.iUnderflowed = 1;
iFrameCount = 0;
iCurrentPosition = (TInt16*) iSoundBuffers[iCurrentBuffer]->Ptr();
return iCurrentPosition;
}
// handles underflow condition
void CGameAudioMS::UnderflowedL()
{
// recreate the stream
//iMdaAudioOutputStream->Stop();
if(iMdaAudioOutputStream) delete iMdaAudioOutputStream;
iMdaAudioOutputStream = CMdaAudioOutputStream::NewL(iListener, iServer);
iMdaAudioOutputStream->Open(&iMdaAudioDataSettings);
iListener.iIsOpen = EFalse; // wait for it to open
//iListener.iHasCopied = ETrue; // but don't wait for last copy to complete
// let it open and feed some stuff to make it happy
User::After(0);
TInt lastBuffer = iCurrentBuffer;
if(--lastBuffer < 0) lastBuffer = KSoundBuffers - 1;
iScheduler->Schedule();
if(!iListener.iIsOpen) WaitForOpenToCompleteL();
iMdaAudioOutputStream->WriteL(*iSoundBuffers[KSoundBuffers]); // special empty fill-up
iMdaAudioOutputStream->WriteL(*iSoundBuffers[lastBuffer]);
iTime = TInt64(0, KBlockTime/4 + KBlockTime);
}
/*
void CGameAudioMS::WaitForCopyToCompleteL()
{
DEBUGPRINT(_L("CGameAudioMS::WaitForCopyToCompleteL"));
while (!iListener.iHasCopied) {
//User::After(0);
iScheduler->Schedule();
}
}
*/
void CGameAudioMS::WaitForOpenToCompleteL()
{
DEBUGPRINT(_L("CGameAudioMS::WaitForOpenToCompleteL"));
TInt count = 20; // 2 seconds
TInt waitPeriod = 100 * 1000;
if(!iListener.iIsOpen) {
// it is often enough to do this
User::After(0);
iScheduler->Schedule();
}
while (!iListener.iIsOpen && --count)
{
User::After(waitPeriod);
iScheduler->Schedule();
}
if (!iListener.iIsOpen)
User::LeaveIfError(KErrNotSupported);
}
void CGameAudioMS::ChangeVolume(TInt aUp)
{
// do nothing
DEBUGPRINT(_L("CGameAudioMS::ChangeVolume(%i)"), aUp);
}
void TGameAudioEventListener::MaoscOpenComplete(TInt aError)
{
DEBUGPRINT(_L("CGameAudioMS::MaoscOpenComplete, error=%d"), aError);
iIsOpen = ETrue;
if(aError) iUnderflowed++;
else iUnderflowed = 0;
}
void TGameAudioEventListener::MaoscBufferCopied(TInt aError, const TDesC8& aBuffer)
{
DEBUGPRINT(_L("CGameAudioMS::MaoscBufferCopied, error=%d"), aError);
// iHasCopied = ETrue;
if(aError) // shit!
iUnderflowed++;
}
void TGameAudioEventListener::MaoscPlayComplete(TInt aError)
{
DEBUGPRINT(_L("CGameAudioMS::MaoscPlayComplete: %i"), aError);
if(aError)
iUnderflowed++; // never happened to me while testing, but just in case
}

View file

@ -1,3 +0,0 @@
EXPORTS
; NEW:
NewL__12CGameAudioMSiiii @ 1 NONAME ; static CGameAudioMS* NewL(TInt aRate, TBool aStereo, TInt aPcmFrames, TInt aBufferedFrames);

View file

@ -1,87 +0,0 @@
/*******************************************************************
*
* File: Audio_mediaserver.h
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2001, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#ifndef __AUDIO_MEDIASERVER_H
#define __AUDIO_MEDIASERVER_H
#include <Mda\Common\Audio.h>
#include <MdaAudioOutputStream.h>
#include "audio.h"
#include "polledas.h"
const TInt KSoundBuffers = 4;
const TInt KBlockTime = 1000000 / 5; // hardcoded: 5 updates/sec
const TInt KMaxLag = 260000; // max sound lag, lower values increase chanse of underflow
const TInt KMaxUnderflows = 50; // max underflows/API errors we are going allow in a row (to prevent lockups)
class TGameAudioEventListener : public MMdaAudioOutputStreamCallback
{
public: // implements MMdaAudioOutputStreamCallback
void MaoscOpenComplete(TInt aError);
void MaoscBufferCopied(TInt aError, const TDesC8& );
void MaoscPlayComplete(TInt aError);
TBool iIsOpen;
// TBool iHasCopied;
TInt iUnderflowed;
};
class CGameAudioMS : public IGameAudio // IGameAudio MUST be specified first!
{
public: // implements IGameAudio
TInt16 *NextFrameL();
TInt16 *DupeFrameL(TInt &aUnderflowed);
TInt16 *ResumeL();
void Pause();
void ChangeVolume(TInt aUp);
public:
~CGameAudioMS();
CGameAudioMS(TInt aRate, TBool aStereo, TInt aPcmFrames, TInt aBufferedFrames);
void ConstructL();
EXPORT_C static CGameAudioMS* NewL(TInt aRate, TBool aStereo, TInt aPcmFrames, TInt aBufferedFrames);
protected:
void WriteBlockL();
void UnderflowedL();
protected:
void WaitForOpenToCompleteL();
// void WaitForCopyToCompleteL();
TInt iRate;
TBool iStereo;
CMdaAudioOutputStream *iMdaAudioOutputStream;
TMdaAudioDataSettings iMdaAudioDataSettings;
TGameAudioEventListener iListener;
CPolledActiveScheduler *iScheduler;
HBufC8* iSoundBuffers[KSoundBuffers+1];
TInt iBufferedFrames;
TInt16* iCurrentPosition;
TInt iCurrentBuffer;
TInt iFrameCount;
TInt iPcmFrames;
CMdaServer* iServer;
TInt64 iTime;
};
#endif /* __AUDIO_MEDIASERVER_H */

View file

@ -1,18 +0,0 @@
TARGET audio_mediaserver.dll
TARGETTYPE dll
UID 0x100039CE 0x1000C196
USERINCLUDE .
USERINCLUDE ..\..\
SYSTEMINCLUDE \epoc32\include
SOURCEPATH .
SOURCE audio_mediaserver.cpp
SOURCE polledas.cpp
LIBRARY EUSER.LIB mediaclientaudiostream.lib mediaclient.lib
deffile .\audio_mediaserver.def
nostrictdef

View file

@ -1,213 +0,0 @@
/*******************************************************************
*
* File: PolledAS.cpp
*
* Author: Peter van Sebille (peter@yipton.net)
*
* (c) Copyright 2002, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
/*
* Oh Lord, forgive me for I have sinned.
* In their infinite wisdom, Symbian Engineers have decided that
* the Active Scheduler's queue of Active Objects is private
* and no getters are provided... sigh.
* This mere mortal will have to excercise the power of C pre-processor
* once more to circumvent the will of the gods.
*/
#include <e32std.h>
// from e32base.h
class CBase
{
public:
IMPORT_C virtual ~CBase();
inline TAny* operator new(TUint aSize,TAny *aBase) {Mem::FillZ(aBase,aSize);return(aBase);}
IMPORT_C TAny* operator new(TUint aSize);
inline TAny* operator new(TUint aSize, TLeave) {return newL(aSize);}
IMPORT_C TAny* operator new(TUint aSize,TUint anExtraSize);
protected:
IMPORT_C CBase();
private:
CBase(const CBase&);
CBase& operator=(const CBase&);
IMPORT_C static TAny* newL(TUint aSize);
};
class CActive : public CBase
{
public:
enum TPriority
{
EPriorityIdle=-100,
EPriorityLow=-20,
EPriorityStandard=0,
EPriorityUserInput=10,
EPriorityHigh=20,
};
public:
IMPORT_C ~CActive();
IMPORT_C void Cancel();
IMPORT_C void Deque();
IMPORT_C void SetPriority(TInt aPriority);
inline TBool IsActive() const {return(iActive);}
inline TBool IsAdded() const {return(iLink.iNext!=NULL);}
inline TInt Priority() const {return iLink.iPriority;}
protected:
IMPORT_C CActive(TInt aPriority);
IMPORT_C void SetActive();
// Pure virtual
virtual void DoCancel() =0;
virtual void RunL() =0;
IMPORT_C virtual TInt RunError(TInt aError);
public:
TRequestStatus iStatus;
private:
TBool iActive;
TPriQueLink iLink;
friend class CActiveScheduler;
// friend class CServer;
friend class CPrivatePolledActiveScheduler; // added
};
class CActiveScheduler : public CBase
{
public:
IMPORT_C CActiveScheduler();
IMPORT_C ~CActiveScheduler();
IMPORT_C static void Install(CActiveScheduler* aScheduler);
IMPORT_C static CActiveScheduler* Current();
IMPORT_C static void Add(CActive* anActive);
IMPORT_C static void Start();
IMPORT_C static void Stop();
IMPORT_C static TBool RunIfReady(TInt& aError, TInt aMinimumPriority);
IMPORT_C static CActiveScheduler* Replace(CActiveScheduler* aNewActiveScheduler);
IMPORT_C virtual void WaitForAnyRequest();
IMPORT_C virtual void Error(TInt anError) const;
private:
void DoStart();
void OwnedStartLoop(TInt& aRunning);
IMPORT_C virtual void OnStarting();
IMPORT_C virtual void OnStopping();
IMPORT_C virtual void Reserved_1();
IMPORT_C virtual void Reserved_2();
friend class CPrivatePolledActiveScheduler; // added
private:
// private interface used through by CActiveSchedulerWait objects
friend class CActiveSchedulerWait;
static void OwnedStart(CActiveSchedulerWait& aOwner);
protected:
inline TInt Level() const {return(iLevel);}
private:
TInt iLevel;
TPriQue<CActive> iActiveQ;
};
class TCleanupItem;
class CleanupStack
{
public:
IMPORT_C static void PushL(TAny* aPtr);
IMPORT_C static void PushL(CBase* aPtr);
IMPORT_C static void PushL(TCleanupItem anItem);
IMPORT_C static void Pop();
IMPORT_C static void Pop(TInt aCount);
IMPORT_C static void PopAndDestroy();
IMPORT_C static void PopAndDestroy(TInt aCount);
IMPORT_C static void Check(TAny* aExpectedItem);
inline static void Pop(TAny* aExpectedItem);
inline static void Pop(TInt aCount, TAny* aLastExpectedItem);
inline static void PopAndDestroy(TAny* aExpectedItem);
inline static void PopAndDestroy(TInt aCount, TAny* aLastExpectedItem);
};
/*
* This will declare CPrivatePolledActiveScheduler as a friend
* of all classes that define a friend. CPrivatePolledActiveScheduler needs to
* be a friend of CActive
*/
//#define friend friend class CPrivatePolledActiveScheduler; friend
/*
* This will change the:
* void DoStart();
* method in CActiveScheduler to:
* void DoStart(); friend class CPrivatePolledActiveScheduler;
* We need this to access the private datamembers in CActiveScheduler.
*/
//#define DoStart() DoStart(); friend class CPrivatePolledActiveScheduler;
//#include <e32base.h>
#include "PolledAS.h"
class CPrivatePolledActiveScheduler : public CActiveScheduler
{
public:
void Schedule();
};
void CPrivatePolledActiveScheduler::Schedule()
{
TDblQueIter<CActive> q(iActiveQ);
q.SetToFirst();
FOREVER
{
CActive *pR=q++;
if (pR)
{
if (pR->IsActive() && pR->iStatus!=KRequestPending)
{
pR->iActive=EFalse;
TRAPD(r,pR->RunL());
break;
}
}
else
break;
}
}
CPolledActiveScheduler::~CPolledActiveScheduler()
{
delete iPrivatePolledActiveScheduler;
}
//static CPolledActiveScheduler* sPolledActiveScheduler = NULL;
CPolledActiveScheduler* CPolledActiveScheduler::NewL()
{
//sPolledActiveScheduler =
CPolledActiveScheduler* self = new(ELeave)CPolledActiveScheduler;
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop();
return self;
}
void CPolledActiveScheduler::ConstructL()
{
iPrivatePolledActiveScheduler = new(ELeave) CPrivatePolledActiveScheduler;
iPrivatePolledActiveScheduler->Install(iPrivatePolledActiveScheduler);
}
void CPolledActiveScheduler::Schedule()
{
iPrivatePolledActiveScheduler->Schedule();
}
/*
CPolledActiveScheduler* CPolledActiveScheduler::Instance()
{
// return (CPolledActiveScheduler*) CActiveScheduler::Current();
return sPolledActiveScheduler;
}
*/

View file

@ -1,2 +0,0 @@
copy %EPOCROOT%\epoc32\release\armi\urel\audio_mediaserver.dll ..\
..\..\..\qconsole-1.52\qtty\release\qtty --qc-addr P800 --qc-channel 5 --user qconsole --pass server --cmds "put d:\system\apps\picodriven\audio_mediaserver.dll ..\audio_mediaserver.dll" exit

View file

@ -1 +0,0 @@
copy %EPOCROOT%\epoc32\release\armi\urel\audio_mediaserver.dll ..\

View file

@ -1,418 +0,0 @@
# CWD \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\
# MMPFile \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA.MMP
# Target AUDIO_MOTOROLA.DLL
# TargetType DLL
# BasicTargetType DLL
# MakefileType GNU
ERASE = @erase 2>>nul
# EPOC DEFINITIONS
EPOCBLD = ..\..\..\..\..\A925SDK\EPOC32\BUILD\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA\ARMI
EPOCTRG = ..\..\..\..\..\A925SDK\EPOC32\RELEASE\ARMI
EPOCLIB = ..\..\..\..\..\A925SDK\EPOC32\RELEASE\ARMI
EPOCLINK = ..\..\..\..\..\A925SDK\EPOC32\RELEASE\ARMI
EPOCSTATLINK = ..\..\..\..\..\A925SDK\EPOC32\RELEASE\ARMI
EPOCASSPLINK = ..\..\..\..\..\A925SDK\EPOC32\RELEASE\MARM
EPOCDATA = \DEV\A925SDK\EPOC32\DATA
EPOCINC = \DEV\A925SDK\EPOC32\INCLUDE
TRGDIR =
DATADIR = Z\SYSTEM\DATA
EPOCBLDUREL = $(EPOCBLD)\UREL
EPOCTRGUREL = $(EPOCTRG)\UREL
EPOCLIBUREL = $(EPOCLIB)\UREL
EPOCLINKUREL = $(EPOCLINK)\UREL
EPOCSTATLINKUREL = $(EPOCSTATLINK)\UREL
EPOCASSPLINKUREL = $(EPOCASSPLINK)\UREL
EPOCBLDUDEB = $(EPOCBLD)\UDEB
EPOCTRGUDEB = $(EPOCTRG)\UDEB
EPOCLIBUDEB = $(EPOCLIB)\UREL
EPOCLINKUDEB = $(EPOCLINK)\UREL
EPOCSTATLINKUDEB = $(EPOCSTATLINK)\UDEB
EPOCASSPLINKUDEB = $(EPOCASSPLINK)\UREL
# EPOC PSEUDOTARGETS
UREL : MAKEWORKUREL RESOURCEUREL
UDEB : MAKEWORKUDEB RESOURCEUDEB
ALL : UREL UDEB
CLEAN CLEANALL : CLEANBUILD CLEANRELEASE CLEANLIBRARY
WHAT WHATALL : WHATUREL WHATUDEB
RESOURCE RESOURCEALL : RESOURCEUREL RESOURCEUDEB
CLEANBUILD CLEANBUILDALL : CLEANBUILDUREL CLEANBUILDUDEB
CLEANRELEASE CLEANRELEASEALL : CLEANRELEASEUREL CLEANRELEASEUDEB
MAKEWORK MAKEWORKALL : MAKEWORKUREL MAKEWORKUDEB
LISTING LISTINGALL : LISTINGUREL LISTINGUDEB
MAKEWORK : MAKEWORKLIBRARY
RESOURCEUREL RESOURCEUDEB : GENERIC_RESOURCE
# must set both PATH and Path to make it work correctly
Path:=X:\DEV\A925SDK\EPOC32\gcc\bin;$(Path)
PATH:=$(Path)
INCDIR = -I "." -I "..\.." -I "..\..\..\..\..\A925SDK\EPOC32\INCLUDE"
GCCFLAGS=-march=armv4t -mthumb-interwork \
-pipe -c -nostdinc -Wall -Wno-ctor-dtor-privacy -Wno-unknown-pragmas
GCCDEFS = -D__SYMBIAN32__ -D__GCC32__ -D__EPOC32__ -D__MARM__ -D__MARM_ARMI__ -D__DLL__ $(USERDEFS)
GCCUREL = gcc -s -fomit-frame-pointer -O $(GCCFLAGS) -DNDEBUG -D_UNICODE $(GCCDEFS)
GCCUDEB = gcc -g -O $(GCCFLAGS) -D_DEBUG -D_UNICODE $(GCCDEFS)
UREL : \
$(EPOCTRGUREL)\AUDIO_MOTOROLA.DLL \
LIBRARY
UDEB : \
$(EPOCTRGUDEB)\AUDIO_MOTOROLA.DLL \
LIBRARY
RESOURCEUREL : MAKEWORKUREL
RESOURCEUDEB : MAKEWORKUDEB
LIBRARY : MAKEWORKLIBRARY $(EPOCLIB)\UREL\AUDIO_MOTOROLA.LIB \DEV\A925SDK\EPOC32\RELEASE\ARM4\UREL\AUDIO_MOTOROLA.LIB \DEV\A925SDK\EPOC32\RELEASE\THUMB\UREL\AUDIO_MOTOROLA.LIB
# REAL TARGET - LIBRARY
$(EPOCLIB)\UREL\AUDIO_MOTOROLA.LIB : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA.DEF
@echo AUDIO_MOTOROLA.LIB: dlltool
@dlltool -m arm_interwork --output-lib "$(EPOCLIB)\UREL\AUDIO_MOTOROLA.LIB" \
--def ".\AUDIO_MOTOROLA.DEF" \
--dllname "AUDIO_MOTOROLA[1000c197].DLL"
\DEV\A925SDK\EPOC32\RELEASE\ARM4\UREL\AUDIO_MOTOROLA.LIB : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA.DEF
@echo AUDIO_MOTOROLA.LIB: dlltool
@dlltool -m arm --output-lib "..\..\..\..\..\A925SDK\EPOC32\RELEASE\ARM4\UREL\AUDIO_MOTOROLA.LIB" \
--def ".\AUDIO_MOTOROLA.DEF" \
--dllname "AUDIO_MOTOROLA[1000c197].DLL"
\DEV\A925SDK\EPOC32\RELEASE\THUMB\UREL\AUDIO_MOTOROLA.LIB : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA.DEF
@echo AUDIO_MOTOROLA.LIB: dlltool
@dlltool -m thumb --output-lib "..\..\..\..\..\A925SDK\EPOC32\RELEASE\THUMB\UREL\AUDIO_MOTOROLA.LIB" \
--def ".\AUDIO_MOTOROLA.DEF" \
--dllname "AUDIO_MOTOROLA[1000c197].DLL"
FREEZE :
perl -S efreeze.pl "\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA.DEF" "$(EPOCBLD)\AUDIO_MOTOROLA.def"
CLEANLIBRARY :
-$(ERASE) "$(EPOCLIB)\UREL\AUDIO_MOTOROLA.LIB"
-$(ERASE) "\DEV\A925SDK\EPOC32\RELEASE\ARM4\UREL\AUDIO_MOTOROLA.LIB"
-$(ERASE) "\DEV\A925SDK\EPOC32\RELEASE\THUMB\UREL\AUDIO_MOTOROLA.LIB"
GENERIC_RESOURCE : GENERIC_MAKEWORK
# REAL TARGET - BUILD VARIANT UREL
WHATUREL : WHATGENERIC
CLEANUREL : CLEANBUILDUREL CLEANRELEASEUREL
CLEANBUILDUREL :
@perl -S ermdir.pl "$(EPOCBLDUREL)"
CLEANRELEASEUREL : CLEANGENERIC
UREL_RELEASEABLES1= \
\DEV\A925SDK\EPOC32\RELEASE\ARM4\UREL\AUDIO_MOTOROLA.LIB \
\DEV\A925SDK\EPOC32\RELEASE\ARMI\UREL\AUDIO_MOTOROLA.DLL \
\DEV\A925SDK\EPOC32\RELEASE\ARMI\UREL\AUDIO_MOTOROLA.DLL.MAP \
\DEV\A925SDK\EPOC32\RELEASE\ARMI\UREL\AUDIO_MOTOROLA.LIB \
\DEV\A925SDK\EPOC32\RELEASE\THUMB\UREL\AUDIO_MOTOROLA.LIB
WHATUREL:
@echo $(UREL_RELEASEABLES1)
CLEANRELEASEUREL:
-$(ERASE) $(UREL_RELEASEABLES1)
LISTINGUREL : MAKEWORKUREL \
LISTINGURELAUDIO_MOTOROLA \
LISTINGURELPOLLEDAS
LIBSUREL= \
$(EPOCSTATLINKUREL)\EDLLSTUB.LIB \
$(EPOCSTATLINKUREL)\EGCC.LIB \
$(EPOCLINKUREL)\EUSER.LIB \
$(EPOCLINKUREL)\MAUDIOFB.LIB \
$(EPOCLINKUREL)\MAUDIOAC.LIB
$(EPOCTRGUREL)\AUDIO_MOTOROLA.DLL : $(EPOCBLDUREL)\AUDIO_MOTOROLA.in \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA.DEF $(EPOCSTATLINKUREL)\EDLL.LIB $(LIBSUREL)
@echo AUDIO_MOTOROLA.DLL: dlltool
@dlltool -m arm_interwork --output-def "$(EPOCBLDUREL)\AUDIO_MOTOROLA.inf" "$(EPOCBLDUREL)\AUDIO_MOTOROLA.in"
@echo AUDIO_MOTOROLA.DLL: perl -S makedef.pl
@perl -S makedef.pl -Deffile "$(EPOCBLDUREL)\AUDIO_MOTOROLA.inf" -Frzfile "\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA.DEF" "$(EPOCBLD)\AUDIO_MOTOROLA.def"
-$(ERASE) "$(EPOCBLDUREL)\AUDIO_MOTOROLA.inf"
@echo AUDIO_MOTOROLA.DLL: dlltool
@dlltool -m arm_interwork --def "$(EPOCBLD)\AUDIO_MOTOROLA.def" \
--output-exp "$(EPOCBLDUREL)\AUDIO_MOTOROLA.exp" \
--dllname "AUDIO_MOTOROLA[1000c197].DLL"
@echo AUDIO_MOTOROLA.DLL: ld
@ld -s -e _E32Dll -u _E32Dll "$(EPOCBLDUREL)\AUDIO_MOTOROLA.exp" --dll \
--base-file "$(EPOCBLDUREL)\AUDIO_MOTOROLA.bas" -o "$(EPOCBLDUREL)\AUDIO_MOTOROLA.DLL" \
"$(EPOCSTATLINKUREL)\EDLL.LIB" --whole-archive "$(EPOCBLDUREL)\AUDIO_MOTOROLA.in" \
--no-whole-archive $(LIBSUREL) $(USERLDFLAGS)
-$(ERASE) "$(EPOCBLDUREL)\AUDIO_MOTOROLA.exp"
-$(ERASE) "$(EPOCBLDUREL)\AUDIO_MOTOROLA.DLL"
@echo AUDIO_MOTOROLA.DLL: dlltool
@dlltool -m arm_interwork \
--def "$(EPOCBLD)\AUDIO_MOTOROLA.def" \
--dllname "AUDIO_MOTOROLA[1000c197].DLL" \
--base-file "$(EPOCBLDUREL)\AUDIO_MOTOROLA.bas" \
--output-exp "$(EPOCBLDUREL)\AUDIO_MOTOROLA.exp"
-$(ERASE) "$(EPOCBLDUREL)\AUDIO_MOTOROLA.bas"
@echo AUDIO_MOTOROLA.DLL: ld
@ld -s -e _E32Dll -u _E32Dll --dll \
"$(EPOCBLDUREL)\AUDIO_MOTOROLA.exp" \
-Map "$(EPOCTRGUREL)\AUDIO_MOTOROLA.DLL.map" -o "$(EPOCBLDUREL)\AUDIO_MOTOROLA.DLL" \
"$(EPOCSTATLINKUREL)\EDLL.LIB" --whole-archive "$(EPOCBLDUREL)\AUDIO_MOTOROLA.in" \
--no-whole-archive $(LIBSUREL) $(USERLDFLAGS)
-$(ERASE) "$(EPOCBLDUREL)\AUDIO_MOTOROLA.exp"
@echo AUDIO_MOTOROLA.DLL: petran
@petran "$(EPOCBLDUREL)\AUDIO_MOTOROLA.DLL" "$@" \
-nocall -uid1 0x10000079 -uid2 0x100039ce -uid3 0x1000c197
-$(ERASE) "$(EPOCBLDUREL)\AUDIO_MOTOROLA.DLL"
OBJECTSUREL= \
$(EPOCBLDUREL)\AUDIO_MOTOROLA.o \
$(EPOCBLDUREL)\POLLEDAS.o
$(EPOCBLDUREL)\AUDIO_MOTOROLA.in : $(OBJECTSUREL)
@echo AUDIO_MOTOROLA.in: if exist (del?)
@if exist "$@" del "$@"
@echo AUDIO_MOTOROLA.in: ar
@ar cr $@ $^
# REAL TARGET - BUILD VARIANT UDEB
WHATUDEB : WHATGENERIC
CLEANUDEB : CLEANBUILDUDEB CLEANRELEASEUDEB
CLEANBUILDUDEB :
@perl -S ermdir.pl "$(EPOCBLDUDEB)"
CLEANRELEASEUDEB : CLEANGENERIC
UDEB_RELEASEABLES1= \
\DEV\A925SDK\EPOC32\RELEASE\ARM4\UREL\AUDIO_MOTOROLA.LIB \
\DEV\A925SDK\EPOC32\RELEASE\ARMI\UDEB\AUDIO_MOTOROLA.DLL \
\DEV\A925SDK\EPOC32\RELEASE\ARMI\UDEB\AUDIO_MOTOROLA.DLL.MAP \
\DEV\A925SDK\EPOC32\RELEASE\ARMI\UREL\AUDIO_MOTOROLA.LIB \
\DEV\A925SDK\EPOC32\RELEASE\THUMB\UREL\AUDIO_MOTOROLA.LIB
WHATUDEB:
@echo $(UDEB_RELEASEABLES1)
CLEANRELEASEUDEB:
-$(ERASE) $(UDEB_RELEASEABLES1)
LISTINGUDEB : MAKEWORKUDEB \
LISTINGUDEBAUDIO_MOTOROLA \
LISTINGUDEBPOLLEDAS
LIBSUDEB= \
$(EPOCSTATLINKUDEB)\EDLLSTUB.LIB \
$(EPOCSTATLINKUDEB)\EGCC.LIB \
$(EPOCLINKUDEB)\EUSER.LIB \
$(EPOCLINKUDEB)\MAUDIOFB.LIB \
$(EPOCLINKUDEB)\MAUDIOAC.LIB
$(EPOCTRGUDEB)\AUDIO_MOTOROLA.DLL : $(EPOCBLDUDEB)\AUDIO_MOTOROLA.in \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA.DEF $(EPOCSTATLINKUDEB)\EDLL.LIB $(LIBSUDEB)
@echo AUDIO_MOTOROLA.DLL: dlltool
@dlltool -m arm_interwork --output-def "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.inf" "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.in"
@echo AUDIO_MOTOROLA.DLL: perl -S makedef.pl
@perl -S makedef.pl -Deffile "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.inf" -Frzfile "\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA.DEF" "$(EPOCBLD)\AUDIO_MOTOROLA.def"
-$(ERASE) "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.inf"
@echo AUDIO_MOTOROLA.DLL: dlltool
@dlltool -m arm_interwork --def "$(EPOCBLD)\AUDIO_MOTOROLA.def" \
--output-exp "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.exp" \
--dllname "AUDIO_MOTOROLA[1000c197].DLL"
@echo AUDIO_MOTOROLA.DLL: ld
@ld -s -e _E32Dll -u _E32Dll "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.exp" --dll \
--base-file "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.bas" -o "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.DLL" \
"$(EPOCSTATLINKUDEB)\EDLL.LIB" --whole-archive "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.in" \
--no-whole-archive $(LIBSUDEB) $(USERLDFLAGS)
-$(ERASE) "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.exp"
-$(ERASE) "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.DLL"
@echo AUDIO_MOTOROLA.DLL: dlltool
@dlltool -m arm_interwork \
--def "$(EPOCBLD)\AUDIO_MOTOROLA.def" \
--dllname "AUDIO_MOTOROLA[1000c197].DLL" \
--base-file "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.bas" \
--output-exp "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.exp"
-$(ERASE) "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.bas"
@echo AUDIO_MOTOROLA.DLL: ld
@ld -e _E32Dll -u _E32Dll --dll \
"$(EPOCBLDUDEB)\AUDIO_MOTOROLA.exp" \
-Map "$(EPOCTRGUDEB)\AUDIO_MOTOROLA.DLL.map" -o "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.DLL" \
"$(EPOCSTATLINKUDEB)\EDLL.LIB" --whole-archive "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.in" \
--no-whole-archive $(LIBSUDEB) $(USERLDFLAGS)
-$(ERASE) "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.exp"
objcopy -X "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.DLL" "$(EPOCTRGUDEB)\AUDIO_MOTOROLA.sym"
@echo AUDIO_MOTOROLA.DLL: petran
@petran "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.DLL" "$@" \
-nocall -uid1 0x10000079 -uid2 0x100039ce -uid3 0x1000c197
-$(ERASE) "$(EPOCBLDUDEB)\AUDIO_MOTOROLA.DLL"
OBJECTSUDEB= \
$(EPOCBLDUDEB)\AUDIO_MOTOROLA.o \
$(EPOCBLDUDEB)\POLLEDAS.o
$(EPOCBLDUDEB)\AUDIO_MOTOROLA.in : $(OBJECTSUDEB)
@echo AUDIO_MOTOROLA.in: if exist (del?)
@if exist "$@" del "$@"
@echo AUDIO_MOTOROLA.in: ar
@ar cr $@ $^
# SOURCES
# Source AUDIO_MOTOROLA.CPP
$(EPOCBLDUREL)\AUDIO_MOTOROLA.lis $(EPOCBLDUREL)\AUDIO_MOTOROLA.o \
$(EPOCBLDUDEB)\AUDIO_MOTOROLA.lis $(EPOCBLDUDEB)\AUDIO_MOTOROLA.o \
: \
\DEV\A925SDK\EPOC32\INCLUDE\CMAUDIOAC.H \
\DEV\A925SDK\EPOC32\INCLUDE\CMAUDIOFB.H \
\DEV\A925SDK\EPOC32\INCLUDE\CMAUDIOFBFORMAT.H \
\DEV\A925SDK\EPOC32\INCLUDE\E32BASE.H \
\DEV\A925SDK\EPOC32\INCLUDE\E32BASE.INL \
\DEV\A925SDK\EPOC32\INCLUDE\E32DEF.H \
\DEV\A925SDK\EPOC32\INCLUDE\E32DES16.H \
\DEV\A925SDK\EPOC32\INCLUDE\E32DES8.H \
\DEV\A925SDK\EPOC32\INCLUDE\E32HAL.H \
\DEV\A925SDK\EPOC32\INCLUDE\E32KEYS.H \
\DEV\A925SDK\EPOC32\INCLUDE\E32PCCD.H \
\DEV\A925SDK\EPOC32\INCLUDE\E32STD.H \
\DEV\A925SDK\EPOC32\INCLUDE\E32STD.INL \
\DEV\A925SDK\EPOC32\INCLUDE\E32SVR.H \
\DEV\A925SDK\EPOC32\INCLUDE\F32FILE.H \
\DEV\A925SDK\EPOC32\INCLUDE\F32FILE.INL \
\DEV\A925SDK\EPOC32\INCLUDE\MAUDIOGLOBAL.H \
\DEV\A925SDK\EPOC32\INCLUDE\RPFILE.H \
\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO.H \
\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA.H \
\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\POLLEDAS.H
$(EPOCBLDUREL)\AUDIO_MOTOROLA.o : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\Audio_motorola.cpp
@echo AUDIO_MOTOROLA.o: gcc
@$(GCCUREL) -I "." $(INCDIR) -o $@ ".\Audio_motorola.cpp"
LISTINGURELAUDIO_MOTOROLA : $(EPOCBLDUREL)\AUDIO_MOTOROLA.lis
@echo ISTINGURELAUDIO_MOTOROLA: perl -S ecopyfile.pl
@perl -S ecopyfile.pl $? \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA.lst.ARMI
$(EPOCBLDUREL)\AUDIO_MOTOROLA.lis : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\Audio_motorola.cpp
$(GCCUREL) -Wa,-adln -I "." $(INCDIR) -o nul: ".\Audio_motorola.cpp" > $@
$(EPOCBLDUDEB)\AUDIO_MOTOROLA.o : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\Audio_motorola.cpp
$(GCCUDEB) -I "." $(INCDIR) -o $@ ".\Audio_motorola.cpp"
LISTINGUDEBAUDIO_MOTOROLA : $(EPOCBLDUDEB)\AUDIO_MOTOROLA.lis
@echo ISTINGUDEBAUDIO_MOTOROLA: perl -S ecopyfile.pl
@perl -S ecopyfile.pl $? \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA.lst.ARMI
$(EPOCBLDUDEB)\AUDIO_MOTOROLA.lis : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\Audio_motorola.cpp
$(GCCUDEB) -Wa,-adln -I "." $(INCDIR) -o nul: ".\Audio_motorola.cpp" > $@
# Source POLLEDAS.CPP
$(EPOCBLDUREL)\POLLEDAS.lis $(EPOCBLDUREL)\POLLEDAS.o \
$(EPOCBLDUDEB)\POLLEDAS.lis $(EPOCBLDUDEB)\POLLEDAS.o \
: \
\DEV\A925SDK\EPOC32\INCLUDE\E32DEF.H \
\DEV\A925SDK\EPOC32\INCLUDE\E32DES16.H \
\DEV\A925SDK\EPOC32\INCLUDE\E32DES8.H \
\DEV\A925SDK\EPOC32\INCLUDE\E32STD.H \
\DEV\A925SDK\EPOC32\INCLUDE\E32STD.INL \
\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\POLLEDAS.H
$(EPOCBLDUREL)\POLLEDAS.o : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\Polledas.cpp
@echo POLLEDAS.o: gcc
@$(GCCUREL) -I "." $(INCDIR) -o $@ ".\Polledas.cpp"
LISTINGURELPOLLEDAS : $(EPOCBLDUREL)\POLLEDAS.lis
@echo ISTINGURELPOLLEDAS: perl -S ecopyfile.pl
@perl -S ecopyfile.pl $? \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\POLLEDAS.lst.ARMI
$(EPOCBLDUREL)\POLLEDAS.lis : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\Polledas.cpp
$(GCCUREL) -Wa,-adln -I "." $(INCDIR) -o nul: ".\Polledas.cpp" > $@
$(EPOCBLDUDEB)\POLLEDAS.o : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\Polledas.cpp
$(GCCUDEB) -I "." $(INCDIR) -o $@ ".\Polledas.cpp"
LISTINGUDEBPOLLEDAS : $(EPOCBLDUDEB)\POLLEDAS.lis
@echo ISTINGUDEBPOLLEDAS: perl -S ecopyfile.pl
@perl -S ecopyfile.pl $? \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\POLLEDAS.lst.ARMI
$(EPOCBLDUDEB)\POLLEDAS.lis : \DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\Polledas.cpp
$(GCCUDEB) -Wa,-adln -I "." $(INCDIR) -o nul: ".\Polledas.cpp" > $@
ROMFILE:
@echo file=\DEV\A925SDK\EPOC32\RELEASE\ARMI\##BUILD##\AUDIO_MOTOROLA.DLL System\Libs\AUDIO_MOTOROLA.DLL
WHATGENERIC CLEANGENERIC :
@rem none
# Rules to create all necessary directories
GENERIC_MAKEWORK : \
\DEV\A925SDK\EPOC32\BUILD\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA\ARMI
MAKEWORKLIBRARY : \
\DEV\A925SDK\EPOC32\RELEASE\ARM4\UREL \
\DEV\A925SDK\EPOC32\RELEASE\ARMI\UREL \
\DEV\A925SDK\EPOC32\RELEASE\THUMB\UREL
MAKEWORKUDEB : \
\DEV\A925SDK\EPOC32\BUILD\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA\ARMI\UDEB \
\DEV\A925SDK\EPOC32\RELEASE\ARMI\UDEB
MAKEWORKUREL : \
\DEV\A925SDK\EPOC32\BUILD\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA\ARMI\UREL \
\DEV\A925SDK\EPOC32\RELEASE\ARMI\UREL
\DEV\A925SDK\EPOC32\BUILD\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA\ARMI \
\DEV\A925SDK\EPOC32\BUILD\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA\ARMI\UDEB \
\DEV\A925SDK\EPOC32\BUILD\DEV\UIQ21\_SRC\PICODRIVEN\AUDIO\MOTOROLA\AUDIO_MOTOROLA\ARMI\UREL \
\DEV\A925SDK\EPOC32\RELEASE\ARM4\UREL \
\DEV\A925SDK\EPOC32\RELEASE\ARMI\UDEB \
\DEV\A925SDK\EPOC32\RELEASE\ARMI\UREL \
\DEV\A925SDK\EPOC32\RELEASE\THUMB\UREL \
:
@echo UREL: perl -S emkdir.pl
@perl -S emkdir.pl $@

View file

@ -1,32 +0,0 @@
/*******************************************************************
*
* File: PolledAS.h
*
* Author: Peter van Sebille (peter@yipton.net)
*
* (c) Copyright 2001, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#ifndef __POLLED_AS_H
#define __POLLED_AS_H
class CPrivatePolledActiveScheduler;
class CPolledActiveScheduler : public CBase
{
public:
~CPolledActiveScheduler();
static CPolledActiveScheduler* NewL();
//static CPolledActiveScheduler* Instance();
void Schedule();
protected:
CPolledActiveScheduler(){};
void ConstructL();
CPrivatePolledActiveScheduler* iPrivatePolledActiveScheduler;
};
#endif /* __POLLED_AS_H */

View file

@ -1,363 +0,0 @@
/*******************************************************************
*
* File: Audio_motorola.cpp
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2001, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
// if only I had Motorola to test this on..
#include "audio_motorola.h"
#ifdef __DEBUG_PRINT_SND
#include <e32svr.h> // RDebug
#define DEBUGPRINT(x...) RDebug::Print(x)
#else
#define DEBUGPRINT(x...)
#endif
GLDEF_C TInt E32Dll(TDllReason)
{
return KErrNone;
}
/*******************************************
*
* CGameAudioMot
*
*******************************************/
CGameAudioMot::CGameAudioMot(TInt aRate, TBool aStereo, TInt aPcmFrames, TInt aBufferedFrames)
: iRate(aRate), iStereo(aStereo), iBufferedFrames(aBufferedFrames), iPcmFrames(aPcmFrames)
{
DEBUGPRINT(_L("CGameAudioMot::CGameAudioMot"));
}
CGameAudioMot* CGameAudioMot::NewL(TInt aRate, TBool aStereo, TInt aPcmFrames, TInt aBufferedFrames)
{
DEBUGPRINT(_L("CGameAudioMot::NewL(%i, %i, %i, %i)"),aRate, aStereo, aPcmFrames, aBufferedFrames);
CGameAudioMot* self = new(ELeave) CGameAudioMot(aRate, aStereo, aPcmFrames, aBufferedFrames);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(); // self
return self;
}
CGameAudioMot::~CGameAudioMot()
{
DEBUGPRINT(_L("CGameAudioMot::~CGameAudioMot()"));
if(iAudioOutputStream) {
iScheduler->Schedule(); // let it finish it's stuff
//iAudioOutputStream->Stop();
delete iAudioOutputStream;
}
if(iAudioControl) delete iAudioControl;
for (TInt i=0 ; i < KSoundBuffers+1; i++) {
delete iSoundBufferPtrs[i];
delete iSoundBuffers[i];
}
// Polled AS
if(iScheduler) delete iScheduler;
}
void CGameAudioMot::ConstructL()
{
iScheduler = CPolledActiveScheduler::NewL();
iSettings.iPCMSettings.iSamplingFreq = (TMSampleRate) iRate;
iSettings.iPCMSettings.iStereo = iStereo;
TInt bytesPerFrame = iStereo ? iPcmFrames << 2 : iPcmFrames << 1;
for (TInt i=0 ; i<KSoundBuffers ; i++)
{
iSoundBuffers[i] = HBufC8::NewL(bytesPerFrame * iBufferedFrames);
iSoundBuffers[i]->Des().FillZ (bytesPerFrame * iBufferedFrames);
iSoundBufferPtrs[i] = new TPtr8( iSoundBuffers[i]->Des() );
}
// because feeding 2 buffers after an underflow is a little too much, but feeding 1 may be not enough,
// prepare this ~50ms empty buffer to additionaly feed after every underflow.
iSoundBuffers[KSoundBuffers] = HBufC8::NewL(bytesPerFrame * (iBufferedFrames / 4));
iSoundBuffers[KSoundBuffers]->Des().FillZ (bytesPerFrame * (iBufferedFrames / 4));
iSoundBufferPtrs[KSoundBuffers] = new TPtr8( iSoundBuffers[KSoundBuffers]->Des() );
iCurrentBuffer = 0;
iListener.iFatalError = iListener.iIsOpen = iListener.iIsCtrlOpen = EFalse;
// here we actually test if we can create and open CMdaAudioOutputStream at all, but really create and use it later.
iAudioOutputStream = CMAudioFB::NewL(EMAudioFBRequestTypeDecode, EMAudioFBFormatPCM, iSettings, iListener);
if(iAudioOutputStream) {
delete iAudioOutputStream;
iAudioOutputStream = 0;
}
// ceate audio control object
iAudioControl = CMAudioAC::NewL(iListener);
}
// returns a pointer to buffer for next frame,
// to be used when iSoundBuffers are used directly
TInt16 *CGameAudioMot::NextFrameL()
{
iCurrentPosition += iPcmFrames << (iStereo?1:0);
if (++iFrameCount == iBufferedFrames)
{
WriteBlockL();
}
iScheduler->Schedule();
if(iListener.iFatalError || iListener.iUnderflowed > KMaxUnderflows) {
if(iAudioOutputStream) delete iAudioOutputStream;
iAudioOutputStream = 0;
return 0;
}
else if(iListener.iUnderflowed) UnderflowedL();
return iCurrentPosition;
}
TInt16 *CGameAudioMot::DupeFrameL(TInt &aUnderflowed)
{
TInt shorts = iStereo ? (iPcmFrames << 1) : iPcmFrames;
if(iFrameCount)
Mem::Copy(iCurrentPosition, iCurrentPosition-shorts, shorts<<1);
else {
TInt lastBuffer = iCurrentBuffer;
if(--lastBuffer < 0) lastBuffer = KSoundBuffers - 1;
Mem::Copy(iCurrentPosition, ((TInt16*) (iSoundBuffers[lastBuffer]->Ptr()))+shorts*(iBufferedFrames-1), shorts<<1);
}
iCurrentPosition += shorts;
if (++iFrameCount == iBufferedFrames)
{
WriteBlockL();
}
iScheduler->Schedule();
if(iListener.iFatalError || iListener.iUnderflowed > KMaxUnderflows) {
if(iAudioOutputStream) delete iAudioOutputStream;
iAudioOutputStream = 0;
return 0;
}
else if((aUnderflowed = iListener.iUnderflowed)) UnderflowedL(); // not again!
return iCurrentPosition;
}
void CGameAudioMot::WriteBlockL()
{
iScheduler->Schedule();
// do not write until stream is open
if(!iListener.iIsOpen) WaitForOpenToCompleteL();
//if(!iListener.iHasCopied) WaitForCopyToCompleteL(); // almost never happens anyway and sometimes even deadlocks?
//iListener.iHasCopied = EFalse;
if(!iListener.iUnderflowed) {
iAudioOutputStream->QueueBufferL(iSoundBufferPtrs[iCurrentBuffer]);
// it is certain we already Queued at least 2 buffers (one just after underflow, another above)
if(!iDecoding) {
iAudioOutputStream->DecodeL();
iDecoding = ETrue;
}
}
iFrameCount = 0;
if (++iCurrentBuffer == KSoundBuffers)
iCurrentBuffer = 0;
iCurrentPosition = (TInt16*) iSoundBuffers[iCurrentBuffer]->Ptr();
}
void CGameAudioMot::Pause()
{
if(!iAudioOutputStream) return;
iScheduler->Schedule();
// iAudioOutputStream->Stop(); // may be this breaks everything in A925?
delete iAudioOutputStream;
iAudioOutputStream = 0;
}
// call this before doing any playback!
TInt16 *CGameAudioMot::ResumeL()
{
DEBUGPRINT(_L("CGameAudioMot::Resume()"));
iScheduler->Schedule();
// we act a bit strange here: simulate buffer underflow, which actually starts audio
iListener.iIsOpen = ETrue;
iListener.iUnderflowed = 1;
iListener.iFatalError = EFalse;
iFrameCount = 0;
iCurrentPosition = (TInt16*) iSoundBuffers[iCurrentBuffer]->Ptr();
return iCurrentPosition;
}
// handles underflow condition
void CGameAudioMot::UnderflowedL()
{
// recreate the stream
if(iAudioOutputStream) delete iAudioOutputStream;
if(iListener.iUnderflowed > 4) {
// HACK: A925 user said sound works for the first time, but fails after pause/resume, etc.
// at the very beginning we create and delete CMAudioFB object, maybe we should do this every time?
iAudioOutputStream = CMAudioFB::NewL(EMAudioFBRequestTypeDecode, EMAudioFBFormatPCM, iSettings, iListener);
if(iAudioOutputStream) delete iAudioOutputStream;
}
iAudioOutputStream = CMAudioFB::NewL(EMAudioFBRequestTypeDecode, EMAudioFBFormatPCM, iSettings, iListener);
iListener.iIsOpen = EFalse; // wait for it to open
iDecoding = EFalse;
//iListener.iHasCopied = ETrue; // but don't wait for last copy to complete
// let it open and feed some stuff to make it happy
User::After(0);
//TInt lastBuffer = iCurrentBuffer;
//if(--lastBuffer < 0) lastBuffer = KSoundBuffers - 1;
iScheduler->Schedule();
if(!iListener.iIsOpen) WaitForOpenToCompleteL();
if(iListener.iUnderflowed) {
// something went wrong again. May be it needs time? Trying to fix something without ability to test is hell.
if(iAudioOutputStream) delete iAudioOutputStream;
iAudioOutputStream = 0;
User::After(50*000);
iScheduler->Schedule();
return;
}
iAudioOutputStream->QueueBufferL(iSoundBufferPtrs[KSoundBuffers]); // try a short buffer with hope to reduce lag
}
void CGameAudioMot::ChangeVolume(TInt aUp)
{
if(iAudioControl && iListener.iIsCtrlOpen)
{
TInt vol = iAudioControl->GetMasterVolume();
TInt max = iAudioControl->GetMaxMasterVolume();
if(aUp) vol++; // adjust volume
else vol--;
if(vol >= 0 && vol <= max)
{
iAudioControl->SetMasterVolume(vol);
}
}
}
void CGameAudioMot::WaitForOpenToCompleteL()
{
DEBUGPRINT(_L("CGameAudioMot::WaitForOpenToCompleteL"));
TInt count = 20; // 2 seconds
TInt waitPeriod = 100 * 1000;
if(!iListener.iIsOpen) {
// it is often enough to do this
User::After(0);
iScheduler->Schedule();
}
while (!iListener.iIsOpen && --count)
{
User::After(waitPeriod);
iScheduler->Schedule();
}
if (!iListener.iIsOpen)
User::LeaveIfError(KErrNotSupported);
}
void TGameAudioEventListener::OnEvent(TMAudioFBCallbackState aState, TInt aError)
{
switch ( aState )
{
case EMAudioFBCallbackStateReady:
iIsOpen = ETrue;
iUnderflowed = 0;
break;
case EMAudioFBCallbackStateDecodeCompleteStopped:
break;
//case EMAudioFBCallbackStateDecodeFileSystemError:
case EMAudioFBCallbackStateDecodeError:
switch( aError )
{
case EMAudioFBCallbackErrorBufferFull:
case EMAudioFBCallbackErrorForcedStop:
case EMAudioFBCallbackErrorForcedClose:
//case EMAudioFBCallbackErrorForcedPause:
case EMAudioFBCallbackErrorPriorityRejection:
case EMAudioFBCallbackErrorAlertModeRejection:
case EMAudioFBCallbackErrorResourceRejection:
case EMAudioFBCallbackErrorUnknown:
iUnderflowed++;
break;
// these look like really bad errors
case EMAudioFBCallbackErrorInvalidParameter:
case EMAudioFBCallbackErrorWrongState:
case EMAudioFBCallbackErrorFormatNotSupported:
case EMAudioFBCallbackErrorFunctionNotSupported:
case EMAudioFBCallbackErrorNoBuffer:
case EMAudioFBCallbackErrorSampleOrBitRateNotSupported:
//case EMAudioFBCallbackErrorPriorityOrPreferenceNotSupported:
//case EMAudioFBCallbackErrorFileSystemFull:
//iFatalError = ETrue;
// who cares, just keep retrying
iUnderflowed++;
break;
default:
iUnderflowed++;
break;
}
// in error condition we also set to open, so that the
// framework would not leave, catch the error and retry
iIsOpen = ETrue;
break;
default:
break;
}
}
void TGameAudioEventListener::OnEvent(TMAudioFBCallbackState aState, TInt aError, TDes8* aBuffer)
{
switch( aState )
{
case EMAudioFBCallbackStateDecodeBufferDecoded:
break;
default:
OnEvent( aState, aError );
break;
}
}
void TGameAudioEventListener::OnEvent(TMAudioACCallbackState aState, TInt aError)
{
if(aState == EMAudioACCallbackStateReady) iIsCtrlOpen = ETrue;
}

View file

@ -1,3 +0,0 @@
EXPORTS
; NEW:
NewL__13CGameAudioMotiiii @ 1 NONAME ; static CGameAudioMot* NewL(TInt aRate, TBool aStereo, TInt aPcmFrames, TInt aBufferedFrames);

View file

@ -1,91 +0,0 @@
/*******************************************************************
*
* File: Audio_motorola.h
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2001, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#ifndef __AUDIO_MEDIASERVER_H
#define __AUDIO_MEDIASERVER_H
#include <cmaudiofb.h>
#include "audio.h"
#include "polledas.h"
const TInt KSoundBuffers = 8;
const TInt KMaxUnderflows = 20; // max underflows/API errors we are going allow in a row (to prevent lockups)
class TGameAudioEventListener : public MMAudioFBObserver, public MMAudioACObserver
{
public:
// Implementation of MMAudioFBObserver
void OnEvent(TMAudioFBCallbackState aState, TInt aError);
void OnEvent(TMAudioFBCallbackState aState, TInt aError, TDes8* aBuffer);
// Implementation of MMAudioACObserver
void OnEvent(TMAudioACCallbackState aState, TInt aError);
TBool iIsOpen;
TBool iIsCtrlOpen;
// TBool iHasCopied;
TInt iUnderflowed;
TBool iFatalError;
};
class CGameAudioMot : public IGameAudio // IGameAudio MUST be specified first!
{
public: // implements IGameAudio
TInt16 *NextFrameL();
TInt16 *DupeFrameL(TInt &aUnderflowed);
TInt16 *ResumeL();
void Pause();
void ChangeVolume(TInt aUp);
public:
~CGameAudioMot();
CGameAudioMot(TInt aRate, TBool aStereo, TInt aPcmFrames, TInt aBufferedFrames);
void ConstructL();
EXPORT_C static CGameAudioMot* NewL(TInt aRate, TBool aStereo, TInt aPcmFrames, TInt aBufferedFrames);
protected:
void WriteBlockL();
void UnderflowedL();
protected:
void WaitForOpenToCompleteL();
TInt iRate;
TBool iStereo;
CMAudioFB *iAudioOutputStream;
CMAudioAC *iAudioControl;
TMAudioFBBufSettings iSettings;
TGameAudioEventListener iListener;
CPolledActiveScheduler *iScheduler;
HBufC8* iSoundBuffers[KSoundBuffers+1];
TPtr8* iSoundBufferPtrs[KSoundBuffers+1];
TInt iBufferedFrames;
TInt16* iCurrentPosition;
TInt iCurrentBuffer;
TInt iFrameCount;
TInt iPcmFrames;
TBool iDecoding;
//TInt64 iTime; // removed because can't test
};
#endif /* __AUDIO_MEDIASERVER_H */

View file

@ -1,20 +0,0 @@
TARGET audio_motorola.dll
TARGETTYPE dll
UID 0x100039CE 0x1000C197
USERINCLUDE .
USERINCLUDE ..\..\
SYSTEMINCLUDE \epoc32\include
SOURCEPATH .
SOURCE audio_motorola.cpp
SOURCE polledas.cpp
LIBRARY EUSER.LIB
LIBRARY maudiofb.lib
LIBRARY maudioac.lib
deffile .\audio_motorola.def
nostrictdef

View file

@ -1,209 +0,0 @@
/*******************************************************************
*
* File: PolledAS.cpp
*
* Author: Peter van Sebille (peter@yipton.net)
*
* (c) Copyright 2002, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
/*
* Oh Lord, forgive me for I have sinned.
* In their infinite wisdom, Symbian Engineers have decided that
* the Active Scheduler's queue of Active Objects is private
* and no getters are provided... sigh.
* This mere mortal will have to excercise the power of C pre-processor
* once more to circumvent the will of the gods.
*/
#include <e32std.h>
// from e32base.h
class CBase
{
public:
IMPORT_C virtual ~CBase();
inline TAny* operator new(TUint aSize,TAny *aBase) {Mem::FillZ(aBase,aSize);return(aBase);}
IMPORT_C TAny* operator new(TUint aSize);
inline TAny* operator new(TUint aSize, TLeave) {return newL(aSize);}
IMPORT_C TAny* operator new(TUint aSize,TUint anExtraSize);
protected:
IMPORT_C CBase();
private:
CBase(const CBase&);
CBase& operator=(const CBase&);
IMPORT_C static TAny* newL(TUint aSize);
};
class CActive : public CBase
{
public:
enum TPriority
{
EPriorityIdle=-100,
EPriorityLow=-20,
EPriorityStandard=0,
EPriorityUserInput=10,
EPriorityHigh=20,
};
public:
IMPORT_C ~CActive();
IMPORT_C void Cancel();
IMPORT_C void Deque();
IMPORT_C void SetPriority(TInt aPriority);
inline TBool IsActive() const {return(iActive);}
inline TBool IsAdded() const {return(iLink.iNext!=NULL);}
inline TInt Priority() const {return iLink.iPriority;}
protected:
IMPORT_C CActive(TInt aPriority);
IMPORT_C void SetActive();
// Pure virtual
virtual void DoCancel() =0;
virtual void RunL() =0;
IMPORT_C virtual TInt RunError(TInt aError);
public:
TRequestStatus iStatus;
private:
TBool iActive;
TPriQueLink iLink;
friend class CActiveScheduler;
// friend class CServer;
friend class CPrivatePolledActiveScheduler; // added
};
//
class CActiveScheduler : public CBase
{
public:
IMPORT_C CActiveScheduler();
IMPORT_C ~CActiveScheduler();
IMPORT_C static void Install(CActiveScheduler* aScheduler);
IMPORT_C static CActiveScheduler* Current();
IMPORT_C static void Add(CActive* anActive);
IMPORT_C static void Start();
IMPORT_C static void Stop();
IMPORT_C static TBool RunIfReady(TInt& aError, TInt aMinimumPriority);
IMPORT_C static CActiveScheduler* Replace(CActiveScheduler* aNewActiveScheduler);
IMPORT_C virtual void WaitForAnyRequest();
IMPORT_C virtual void Error(TInt anError) const;
private:
void DoStart();
IMPORT_C virtual void OnStarting();
IMPORT_C virtual void OnStopping();
IMPORT_C virtual void Reserved_1();
IMPORT_C virtual void Reserved_2();
friend class CPrivatePolledActiveScheduler; // added
protected:
inline TInt Level() const;
private:
TInt iLevel;
TPriQue<CActive> iActiveQ;
};
class TCleanupItem;
class CleanupStack
{
public:
IMPORT_C static void PushL(TAny* aPtr);
IMPORT_C static void PushL(CBase* aPtr);
IMPORT_C static void PushL(TCleanupItem anItem);
IMPORT_C static void Pop();
IMPORT_C static void Pop(TInt aCount);
IMPORT_C static void PopAndDestroy();
IMPORT_C static void PopAndDestroy(TInt aCount);
IMPORT_C static void Check(TAny* aExpectedItem);
inline static void Pop(TAny* aExpectedItem);
inline static void Pop(TInt aCount, TAny* aLastExpectedItem);
inline static void PopAndDestroy(TAny* aExpectedItem);
inline static void PopAndDestroy(TInt aCount, TAny* aLastExpectedItem);
};
/*
* This will declare CPrivatePolledActiveScheduler as a friend
* of all classes that define a friend. CPrivatePolledActiveScheduler needs to
* be a friend of CActive
*/
//#define friend friend class CPrivatePolledActiveScheduler; friend
/*
* This will change the:
* void DoStart();
* method in CActiveScheduler to:
* void DoStart(); friend class CPrivatePolledActiveScheduler;
* We need this to access the private datamembers in CActiveScheduler.
*/
//#define DoStart() DoStart(); friend class CPrivatePolledActiveScheduler;
//#include <e32base.h>
#include "PolledAS.h"
class CPrivatePolledActiveScheduler : public CActiveScheduler
{
public:
void Schedule();
};
void CPrivatePolledActiveScheduler::Schedule()
{
TDblQueIter<CActive> q(iActiveQ);
q.SetToFirst();
FOREVER
{
CActive *pR=q++;
if (pR)
{
if (pR->IsActive() && pR->iStatus!=KRequestPending)
{
pR->iActive=EFalse;
TRAPD(r,pR->RunL());
break;
}
}
else
break;
}
}
CPolledActiveScheduler::~CPolledActiveScheduler()
{
delete iPrivatePolledActiveScheduler;
}
//static CPolledActiveScheduler* sPolledActiveScheduler = NULL;
CPolledActiveScheduler* CPolledActiveScheduler::NewL()
{
//sPolledActiveScheduler =
CPolledActiveScheduler* self = new(ELeave)CPolledActiveScheduler;
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop();
return self;
}
void CPolledActiveScheduler::ConstructL()
{
iPrivatePolledActiveScheduler = new(ELeave) CPrivatePolledActiveScheduler;
iPrivatePolledActiveScheduler->Install(iPrivatePolledActiveScheduler);
}
void CPolledActiveScheduler::Schedule()
{
iPrivatePolledActiveScheduler->Schedule();
}
/*
CPolledActiveScheduler* CPolledActiveScheduler::Instance()
{
// return (CPolledActiveScheduler*) CActiveScheduler::Current();
return sPolledActiveScheduler;
}
*/

View file

@ -1,2 +0,0 @@
copy %EPOCROOT%\epoc32\release\armi\urel\audio_motorola.dll ..\
..\..\..\qconsole-1.52\qtty\release\qtty --qc-addr P800 --qc-channel 5 --user qconsole --pass server --cmds "put d:\system\apps\picodriven\audio_motorola.dll ..\audio_motorola.dll" exit

View file

@ -1 +0,0 @@
copy %EPOCROOT%\epoc32\release\armi\urel\audio_motorola.dll ..\

View file

@ -1,11 +0,0 @@
extern "C" {
void vidConvCpyRGB444(void *to, void *from, int pixels);
void vidConvCpyRGB565(void *to, void *from, int pixels);
void vidConvCpyRGB32 (void *to, void *from, int pixels);
// warning: the functions below will reboot the phone if used incorrectly!
void vidConvCpyM2_16_90 (void *to, void *from, int width); // width is in blocks of 8 pixels
void vidConvCpyM2_16_270 (void *to, void *from, int width);
void vidConvCpyM2_RGB32_90 (void *to, void *from, int width);
void vidConvCpyM2_RGB32_270(void *to, void *from, int width);
}

View file

@ -1,432 +0,0 @@
@ assembly "optimized" blitter and copy functions
@ all pointers must be word-aligned
@ (c) Copyright 2006, notaz
@ All Rights Reserved
@ Convert 0000bbb0 ggg0rrr0
@ to 0000rrr0 ggg0bbb0
@ r2,r3 - scratch, lr = 0x000F000F
.macro convRGB444 reg
and r2, \reg, lr @ r2=red
and r3, \reg, lr, lsl #8 @ r3=blue
and \reg, \reg, lr, lsl #4 @ green stays in place
orr \reg, \reg, r2, lsl #8 @ add red back
orr \reg, \reg, r3, lsr #8 @ add blue back
.endm
.global vidConvCpyRGB444 @ void *to, void *from, int pixels
vidConvCpyRGB444:
stmfd sp!, {r4-r11,lr}
mov r12, r2, lsr #4 @ repeats
mov lr, #0xF0000
orr lr, lr, #0xF @ lr == pattern 0x000F000F
.loopRGB444:
subs r12, r12, #1
@ I first thought storing multiple registers would be faster,
@ but this doesn't seem to be the case, probably because of
@ slow video memory we are dealing with
ldmia r1!, {r4-r11}
convRGB444 r4
str r4, [r0], #4
convRGB444 r5
str r5, [r0], #4
convRGB444 r6
str r6, [r0], #4
convRGB444 r7
str r7, [r0], #4
convRGB444 r8
str r8, [r0], #4
convRGB444 r9
str r9, [r0], #4
convRGB444 r10
str r10, [r0], #4
convRGB444 r11
str r11, [r0], #4
bgt .loopRGB444
ldmfd sp!, {r4-r11,lr}
bx lr
@ Convert 0000bbb0 ggg0rrr0
@ to rrr00ggg 000bbb00
@ r2,r3 - scratch, lr = 0x07800780
.macro convRGB565 reg
and r2, \reg, lr, lsr #7 @ r2=red
and r3, \reg, lr, lsl #1 @ r3=blue
and \reg, lr, \reg,lsl #3 @ green stays, but needs shifting
orr \reg, \reg, r2, lsl #12 @ add red back
orr \reg, \reg, r3, lsr #7 @ add blue back
.endm
.global vidConvCpyRGB565 @ void *to, void *from, int pixels
vidConvCpyRGB565:
stmfd sp!, {r4-r11,lr}
mov r12, r2, lsr #4 @ repeats
mov lr, #0x07800000
orr lr, lr, #0x780 @ lr == pattern 0x07800780
.loopRGB565:
subs r12, r12, #1
ldmia r1!, {r4-r11}
convRGB565 r4
str r4, [r0], #4
convRGB565 r5
str r5, [r0], #4
convRGB565 r6
str r6, [r0], #4
convRGB565 r7
str r7, [r0], #4
convRGB565 r8
str r8, [r0], #4
convRGB565 r9
str r9, [r0], #4
convRGB565 r10
str r10, [r0], #4
convRGB565 r11
str r11, [r0], #4
bgt .loopRGB565
ldmfd sp!, {r4-r11,lr}
bx lr
@ Convert 0000bbb0 ggg0rrr0 0000bbb0 ggg0rrr0
@ to 00000000 rrr00000 ggg00000 bbb00000 ...
@ r2,r3 - scratch, lr = 0x0000F000
@ rin - src reg, rout - dest reg (can be same for both; rout can be r3)
.macro convRGB32_l rout rin
and r2, \rin, lr, lsr #12 @ r2=red
and r3, \rin, lr, lsr #4 @ r3=blue
orr r2, r3, r2, lsl #24
and \rout, lr, \rin, lsl #8 @ green stays, but needs shifting
orr \rout, \rout, r2, lsr #4 @ add red+blue back
.endm
@ r2,r3 - scratch, lr = 0x0000F000
@ rin - src reg, rout - dest reg (can be same for both; rout can be r3)
.macro convRGB32_h rout rin
and r2, \rin, lr, lsl #4 @ r2=red
mov r3, \rin, lsr #24 @ r3=blue
orr r2, r3, r2
and \rout, lr, \rin, lsr #8 @ green
orr \rout, \rout, r2, lsl #4
.endm
@ slightly faster conversion, saves 1 opcode, writes output
@ lr = 0x00F000F0, out: r3=lower_pix, r2=higher_pix; trashes rin
.macro convRGB32_2 rin rethigh=0
and r2, lr, \rin, lsr #4 @ blue
and r3, \rin, lr
orr r2, r2, r3, lsl #8 @ g0b0g0b0
mov r3, r2, lsl #16 @ g0b00000
and \rin,lr, \rin, ror #12 @ 00r000r0 (reversed)
orr r3, r3, \rin, lsr #16 @ g0b000r0
mov r3, r3, ror #16 @ r3=low
str r3, [r0], #4
mov r2, r2, lsr #16
.if \rethigh
orr \rin,r2, \rin, lsl #16
.else
orr r2, r2, \rin, lsl #16
str r2, [r0], #4
.endif
.endm
.global vidConvCpyRGB32 @ void *to, void *from, int pixels
vidConvCpyRGB32:
stmfd sp!, {r4-r7,lr}
mov r12, r2, lsr #3 @ repeats
mov lr, #0x00F00000
orr lr, lr, #0x00F0
.loopRGB32:
subs r12, r12, #1
ldmia r1!, {r4-r7}
convRGB32_2 r4
convRGB32_2 r5
convRGB32_2 r6
convRGB32_2 r7
bgt .loopRGB32
ldmfd sp!, {r4-r7,lr}
bx lr
@ -------- M2 stuff ---------
.bss
tmpstore1d: .long
.text
tmpstore1: .long tmpstore1d
@ r3 - scratch, ru - reg with 2 pixels from upper col, rl - ... lower col
.macro rot_str16_90 ru rl
mov r3, \rl,lsl #16
mov r3, r3, lsr #16
orr r3, r3, \ru, lsl #16
str r3, [r0], #208*2
mov r3, \ru,lsr #16
mov r3, r3, lsl #16
orr r3, r3, \rl, lsr #16
str r3, [r0], #208*2
.endm
.global vidConvCpyM2_16_90 @ void *to, void *from, int width
vidConvCpyM2_16_90:
stmfd sp!, {r4-r11,lr}
ldr r4, =tmpstore1
str sp, [r4] @ save sp, we will need sp reg..
mov sp, r0 @ .. to store our dst
@ crashing beyond this point will be fatal (phone reboots), as Symbian OS expects sp to always point to stack
sub r2, r2, #1
mov r12, #0x00670000
orr r12, r12, r2, lsl #24
orr r12, r12, r2 @ r12 == ((208-2)/2 << 16) | ((width-1)<<24) | (width-1)
add r0, r0, #206*2
add r1, r1, #8*2 @ skip left border
add lr, r1, #328*2
.loopM2_16_90:
subs r12, r12, #1<<24
ldmia r1!, {r4-r7}
ldmia lr!, {r8-r11}
rot_str16_90 r4 r8
rot_str16_90 r5 r9
rot_str16_90 r6 r10
rot_str16_90 r7 r11
bpl .loopM2_16_90
add r12, r12, #1<<24
subs r12, r12, #0x00010000
bmi .loopM2_16_90_end
add r0, sp, r12, lsr #14 @ calculate new dst pointer
orr r12, r12, r12, lsl #24 @ restore the width counter
@ skip remaining pixels on these 2 lines
mov r4, #328/8-1 @ width of mode2 in line_pixels/8
sub r4, r4, r12, lsr #24
add r1, lr, r4, lsl #4 @ skip src pixels
add lr, r1, #328*2
b .loopM2_16_90
.loopM2_16_90_end:
@ restore sp
ldr r4, =tmpstore1
ldr sp, [r4]
ldmfd sp!, {r4-r11,lr}
bx lr
@ r3 - scratch, ru - reg with 2 pixels from upper col, rl - ... lower col (for right-to-left copies)
.macro rot_str16_270 ru rl
mov r3, \rl,lsr #16
mov r3, r3, lsl #16
orr r3, r3, \ru, lsr #16
str r3, [r0], #208*2
mov r3, \ru,lsl #16
mov r3, r3, lsr #16
orr r3, r3, \rl, lsl #16
str r3, [r0], #208*2
.endm
.global vidConvCpyM2_16_270 @ void *to, void *from, int width
vidConvCpyM2_16_270:
stmfd sp!, {r4-r11,lr}
ldr r4, =tmpstore1
str sp, [r4] @ save sp, we will need sp reg to store our dst
sub r2, r2, #1
mov r12, #0x00670000
orr r12, r12, r2, lsl #24
orr r12, r12, r2 @ r12 == ((208-2)/2 << 16) | ((width-1)<<24) | (width-1)
add r1, r1, #328*2 @ skip left border+1line
add lr, r1, #328*2
add sp, r0, #206*2 @ adjust for algo
.loopM2_16_270:
subs r12, r12, #1<<24
ldmdb r1!, {r4-r7}
ldmdb lr!, {r8-r11}
rot_str16_270 r7 r11 @ update the screen in incrementing direction, reduces tearing slightly
rot_str16_270 r6 r10
rot_str16_270 r5 r9
rot_str16_270 r4 r8
bpl .loopM2_16_270
add r12, r12, #1<<24
subs r12, r12, #0x00010000
bmi .loopM2_16_90_end @ same end as in 90
sub r0, sp, r12, lsr #14 @ calculate new dst pointer
orr r12, r12, r12, lsl #24 @ restore the width counter
@ skip remaining pixels on these 2 lines
mov r4, #328/8-1 @ width of mode2 in line_pixels/8
sub r4, r4, r12, lsr #24
sub r1, lr, r4, lsl #4 @ skip src pixels
add r1, r1, #328*2*2
add lr, r1, #328*2
b .loopM2_16_270
.global vidConvCpyM2_RGB32_90 @ void *to, void *from, int width
vidConvCpyM2_RGB32_90:
stmfd sp!, {r4-r10,lr}
mov lr, #0x00F00000
orr lr, lr, #0x00F0
mov r12, #208/4 @ row counter
mov r10, r2, lsl #2 @ we do 2 pixel wide copies
add r8, r0, #208*4 @ parallel line
add r1, r1, #0x21000
add r1, r1, #0x00280 @ r1+=328*207*2+8*2
mov r9, r1
.loopM2RGB32_90:
subs r12, r12, #1
@ at first this loop was written differently: src pixels were fetched with ldm's and
@ dest was not sequential. It ran nearly 2 times slower. It seems it is very important
@ to do sequential memory access on those items, which we have more (to offload addressing bus?).
ldr r4, [r1], #-328*2
ldr r5, [r1], #-328*2
ldr r6, [r1], #-328*2
ldr r7, [r1], #-328*2
convRGB32_2 r4, 1
convRGB32_2 r5, 1
convRGB32_2 r6, 1
convRGB32_2 r7, 1
str r4, [r8], #4
str r5, [r8], #4
str r6, [r8], #4
str r7, [r8], #4
bne .loopM2RGB32_90
subs r10, r10, #1
ldmeqfd sp!, {r4-r10,pc} @ return
mov r12, #208/4 @ restore row counter
mov r0, r8 @ set new dst pointer
add r8, r0, #208*4
add r9, r9, #2*2 @ fix src pointer
mov r1, r9
b .loopM2RGB32_90
@ converter for vidConvCpyM2_RGB32_270
@ lr = 0x00F000F0, out: r3=lower_pix, r2=higher_pix; trashes rin
.macro convRGB32_3 rin
and r2, lr, \rin, lsr #4 @ blue
and r3, \rin, lr
orr r2, r2, r3, lsl #8 @ g0b0g0b0
mov r3, r2, lsl #16 @ g0b00000
and \rin,lr, \rin, ror #12 @ 00r000r0 (reversed)
orr r3, r3, \rin, lsr #16 @ g0b000r0
mov r2, r2, lsr #16
orr r2, r2, \rin, lsl #16
str r2, [r0], #4
mov \rin,r3, ror #16 @ r3=low
.endm
.global vidConvCpyM2_RGB32_270 @ void *to, void *from, int width
vidConvCpyM2_RGB32_270:
stmfd sp!, {r4-r10,lr}
mov lr, #0x00F00000
orr lr, lr, #0x00F0
mov r12, #208/4 @ row counter
mov r10, r2, lsl #2 @ we do 2 pixel wide copies (right to left)
add r8, r0, #208*4 @ parallel line
add r1, r1, #326*2
mov r9, r1
.loopM2RGB32_270:
subs r12, r12, #1
ldr r4, [r1], #328*2
ldr r5, [r1], #328*2
ldr r6, [r1], #328*2
ldr r7, [r1], #328*2
convRGB32_3 r4
convRGB32_3 r5
convRGB32_3 r6
convRGB32_3 r7
str r4, [r8], #4
str r5, [r8], #4
str r6, [r8], #4
str r7, [r8], #4
bne .loopM2RGB32_270
subs r10, r10, #1
ldmeqfd sp!, {r4-r10,pc} @ return
mov r12, #208/4 @ restore row counter
mov r0, r8 @ set new dst pointer
add r8, r0, #208*4
sub r9, r9, #2*2 @ fix src pointer
mov r1, r9
b .loopM2RGB32_270

View file

@ -1,241 +0,0 @@
#include <e32svr.h> // RDebug
#include "debug.h"
#ifdef __WINS__
void ExceptionHandler(TExcType exc) {}
#else
static const wchar_t * const exception_names[] = {
L"General",
L"IntegerDivideByZero",
L"SingleStep",
L"BreakPoint",
L"IntegerOverflow",
L"BoundsCheck",
L"InvalidOpCode",
L"DoubleFault",
L"StackFault",
L"AccessViolation",
L"PrivInstruction",
L"Alignment",
L"PageFault",
L"FloatDenormal",
L"FloatDivideByZero",
L"FloatInexactResult",
L"FloatInvalidOperation",
L"FloatOverflow",
L"FloatStackCheck",
L"FloatUnderflow",
L"Abort",
L"Kill",
L"DataAbort",
L"CodeAbort",
L"MaxNumber",
L"InvalidVector",
L"UserInterrupt",
L"Unknown"
};
static void getASpace(TUint *code_start, TUint *code_end, TUint *stack_start, TUint *stack_end)
{
TUint pc, sp;
RChunk chunk;
TFullName chunkname;
TFindChunk findChunk(_L("*"));
asm volatile ("str pc, %0" : "=m" (pc) );
asm volatile ("str sp, %0" : "=m" (sp) );
while( findChunk.Next(chunkname) != KErrNotFound ) {
chunk.Open(findChunk);
if((TUint)chunk.Base()+chunk.Bottom() < pc && pc < (TUint)chunk.Base()+chunk.Top()) {
if(code_start) *code_start = (TUint)chunk.Base()+chunk.Bottom();
if(code_end) *code_end = (TUint)chunk.Base()+chunk.Top();
} else
if((TUint)chunk.Base()+chunk.Bottom() < sp && sp < (TUint)chunk.Base()+chunk.Top()) {
if(stack_start) *stack_start = (TUint)chunk.Base()+chunk.Bottom();
if(stack_end) *stack_end = (TUint)chunk.Base()+chunk.Top();
}
chunk.Close();
}
}
// tmp
#if defined(__DEBUG_PRINT)
extern "C" char *debugString();
#endif
// our very own exception handler
void ExceptionHandler(TExcType exc)
{
TUint lr, sp, i;
TUint stack_end = 0; // ending address of our stack chunk
TUint code_start = 0, code_end = 0; // starting and ending addresses of our code chunk
TUint guessed_address = 0;
asm volatile ("str lr, %0" : "=m" (lr) );
asm volatile ("str sp, %0" : "=m" (sp) );
// first get some info about the chunks we live in
getASpace(&code_start, &code_end, 0, &stack_end);
// now we begin some black magic tricks
// we go up our stack until we pass our caller address
for(; sp < stack_end; sp += 4)
if(*(TUint *)sp == lr) break;
// there might be mirored caller address
for(i = sp + 4; i < sp + 0x300 && i < stack_end; i += 4)
if(*(TUint *)i == lr) { sp = i; break; }
// aah, it is always 0x9c bytes away from the caller address in my firmware,
// don't know how to detect it in any other way
sp += 0x9c;
guessed_address = *(TUint *)sp;
// output the info
TUint exec_show = exc;
if(exec_show > 27) exec_show = 27;
TPtrC ptrExc((TUint16 *) exception_names[exec_show]);
RDebug::Print(_L("!!!Exception %i (%S) @ 0x%08x (guessed; relative=0x%08x)"), exc, &ptrExc, guessed_address, guessed_address - code_start);
#ifdef __DEBUG_PRINT_FILE
DEBUGPRINT( _L("!!!Exception %i (%S) @ 0x%08x (guessed; relative=0x%08x)"), exc, &ptrExc, guessed_address, guessed_address - code_start);
#endif
TBuf<148> buff1;
TBuf<10> buff2;
buff1.Copy(_L(" guessed stack: "));
for(sp += 4, i = 0; i < 5 && sp < stack_end; sp += 4) {
if((*(TUint *)sp >> 28) == 5) {
if(i++) buff1.Append(_L(", "));
buff2.Format(_L("0x%08x"), *(TUint *)sp);
buff1.Append(buff2);
}
else if(code_start < *(TUint *)sp && *(TUint *)sp < code_end) {
if(i++) buff1.Append(_L(", "));
buff2.Format(_L("0x%08x"), *(TUint *)sp);
buff1.Append(buff2);
buff1.Append(_L(" ("));
buff2.Format(_L("0x%08x"), *(TUint *)sp - code_start);
buff1.Append(buff2);
buff1.Append(_L(")"));
}
}
RDebug::Print(_L("%S"), &buff1);
#ifdef __DEBUG_PRINT_FILE
DEBUGPRINT(_L("%S"), &buff1);
#endif
// tmp
#if defined(__DEBUG_PRINT)
char *ps, *cstr = debugString();
for(ps = cstr; *ps; ps++) {
if(*ps == '\n') {
*ps = 0;
dprintf(cstr);
cstr = ps+1;
}
}
#endif
// RDebug::Print(_L("Stack dump:"));
// asm volatile ("str sp, %0" : "=m" (sp) );
// for(TUint i = sp+0x400; i >= sp-16; i-=4)
// RDebug::Print(_L("%08x: %08x"), i, *(int *)i);
// more descriptive replacement of "KERN-EXEC 3" panic
buff1.Format(_L("K-EX3: %S"), &ptrExc);
User::Panic(buff1, exc);
}
#endif // ifdef __WINS__
#if defined(__DEBUG_PRINT) || defined(__WINS__)
#ifndef __DLL__
// c string dumper for RDebug::Print()
static TBuf<1024> sTextBuffer;
TDesC* DO_CONV(const char* s)
{
TPtrC8 text8((TUint8*) (s));
sTextBuffer.Copy(text8);
return &sTextBuffer;
}
#endif
#ifdef __DEBUG_PRINT_C
#include <stdarg.h> // va_*
#include <stdio.h> // vsprintf
// debug print from c code
extern "C" void dprintf(char *format, ...)
{
va_list args;
char buffer[512];
va_start(args,format);
vsprintf(buffer,format,args);
va_end(args);
DEBUGPRINT(_L("%S"), DO_CONV(buffer));
}
#endif
#ifdef __DEBUG_PRINT_FILE
#include <f32file.h>
// note: uses tls, leaks some mem
void debugPrintFileInit()
{
RFs *fs = new(ELeave) RFs;
fs->Connect();
RFile *file = new(ELeave) RFile;
// try to open
TInt res = file->Open(*fs, _L("C:\\documents\\Media files\\other\\snes9x.log"), EFileWrite|EFileShareAny);
if(res) res = file->Open(*fs, _L("C:\\snes9x.log"), EFileWrite|EFileShareAny);
if(!res) { TInt size; file->Size(size); file->Seek(ESeekStart, size); }
// try to create
if(res) res = file->Create(*fs, _L("C:\\documents\\Media files\\other\\snes9x.log"), EFileWrite|EFileShareAny);
if(res) res = file->Create(*fs, _L("C:\\snes9x.log"), EFileWrite|EFileShareAny);
Dll::SetTls(res ? 0 : file);
}
// debug print to file
void debugPrintFile(TRefByValue<const TDesC> aFmt, ...)
{
// get RFile
RFile *file = (RFile *) Dll::Tls();
if(!file) return; // shit!
TTime now; now.UniversalTime();
TBuf<512> tmpBuff;
TBuf8<512> tmpBuff8;
TInt size;
file->Size(size); file->Seek(ESeekStart, size); // something else could have written to the file
now.FormatL(tmpBuff, _L("%H:%T:%S.%C: "));
tmpBuff8.Copy(tmpBuff);
file->Write(tmpBuff8);
VA_LIST args;
VA_START(args, aFmt);
tmpBuff.FormatList(aFmt, args);
VA_END(args);
tmpBuff8.Copy(tmpBuff);
file->Write(tmpBuff8);
file->Write(TPtrC8((TUint8 const *) "\r\n"));
file->Flush();
}
#endif
#endif

View file

@ -1,27 +0,0 @@
#include <e32std.h>
#define __DEBUG_PRINT_C
#if defined(__DEBUG_PRINT) || defined(__WINS__)
#include <e32svr.h> // RDebug
#ifdef __DEBUG_PRINT_FILE
void debugPrintFileInit();
void debugPrintFile(TRefByValue<const TDesC> aFmt, ...);
#define DEBUG_PRINT_FILE_INIT debugPrintFileInit
#define DEBUGPRINT debugPrintFile
#else
#define DEBUG_PRINT_FILE_INIT()
#define DEBUGPRINT RDebug::Print
#endif
TDesC* DO_CONV(const char* s);
#ifdef __DEBUG_PRINT_C
#ifdef __cplusplus
extern "C"
#endif
void dprintf(char *format, ...);
#endif
#else
#define DEBUGPRINT(x...)
#endif
void ExceptionHandler(TExcType exc);

View file

@ -1,644 +0,0 @@
/*******************************************************************
*
* File: App.cpp
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2002, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#include "app.h"
// #include "picodriven.mbg" // bitmap identifiers
#include "picodriven.rsg"
#include <eikenv.h>
#include <qbtselectdlg.h>
//#include <gulutil.h>
//#include <bautils.h>
#include <eikmenub.h> // CEikMenuBar
#include <apgtask.h> // TApaSystemEvent
#include "Dialogs.h"
CApaDocument* CPicolApplication::CreateDocumentL()
{
return new (ELeave) CPicolDocument(*this);
}
CPicolDocument::CPicolDocument(CEikApplication& aApp)
: CEikDocument(aApp)
{
}
CPicolDocument::~CPicolDocument()
{
}
CEikAppUi* CPicolDocument::CreateAppUiL()
{
return new(ELeave) CPicolAppUi;
}
////////////////////////////////////////////////////////////////
//
// class CPicolAppUi
//
////////////////////////////////////////////////////////////////
CPicolAppUi::CPicolAppUi()
: iCurrentLConfig(iCurrentConfig)
{
// set default config
Mem::FillZ(&iCurrentConfig, sizeof(iCurrentConfig));
iCurrentConfig.iFlags = 1; // use_sram
iCurrentConfig.iFrameskip = TPicoConfig::PFSkipAuto;
iCurrentConfig.iScreenRotation = TPicoConfig::PRot90;
}
CPicolAppUi::~CPicolAppUi()
{
delete iAppView;
DeregisterView(*iFOView);
delete iFOView;
DeregisterView(*iFCView);
delete iFCView;
}
void CPicolAppUi::ConstructL()
{
BaseConstructL();
// load config
iCurrentLConfig.Load();
iAppView=new(ELeave) CEPicolAppView;
iAppView->ConstructL(ClientRect());
iFOView=new(ELeave) CPicolFOView(*iAppView);
RegisterViewL(*iFOView);
iFCView=new(ELeave) CPicolFCView(*iAppView);
RegisterViewL(*iFCView);
}
void CPicolAppUi::HandleCommandL(TInt aCommand)
{
TInt oldFrameskip = iCurrentConfig.iFrameskip;
TInt res;
// give time for config dialog destruction
if(iAfterConfigDialog) {
iAfterConfigDialog = EFalse;
TTime now; now.UniversalTime();
if(now.MicroSecondsFrom(iConfigDialogClosed).Int64().Low() < 2500*1000)
User::After(2500*1000-now.MicroSecondsFrom(iConfigDialogClosed).Int64().Low());
}
switch (aCommand)
{
case EEikCmdPicoLoadState:
if(iGameRunner) {
CEikonEnv::Static()->BusyMsgL(_L("Loading State"));
res = ss.SendReceive(PicoMsgLoadState, 0);
CEikonEnv::Static()->BusyMsgCancel();
// emu doesn't start to run if load fails, so we can display this
if(res) CEikonEnv::Static()->InfoMsg(_L("Load Failed"));
}
break;
case EEikCmdPicoSaveState:
if(iGameRunner) {
CEikonEnv::Static()->BusyMsgL(_L("Saving State"));
res = ss.SendReceive(PicoMsgSaveState, 0);
CEikonEnv::Static()->BusyMsgCancel();
if(res) CEikonEnv::Static()->InfoMsg(_L("Save Failed"));
}
break;
case EEikCmdPicoLoadROM:
DisplayOpenROMDialogL();
break;
case EEikCmdPicoResume:
ss.Send(PicoMsgResume, 0);
iEmuRunning = ETrue;
break;
case EEikCmdPicoReset:
ss.Send(PicoMsgReset, 0);
iEmuRunning = ETrue;
break;
case EEikCmdPicoKeys:
if(!iGameRunner) RunGameL();
ss.Send(PicoMsgKeys, 0);
iEmuRunning = ETrue;
break;
case EEikCmdPicoSettings:
DisplayConfigDialogL();
break;
case EEikCmdHelpAbout: // EEikCmdPicoAbout:
DisplayAboutDialogL();
break;
// standard identifier must be used here, TApaTask::EndTask() and probably others send it
case EEikCmdExit: // EEikCmdPicoExit:
if(iGameRunner) {
iQuitting = ETrue;
iExitForcer = CExitForcer::NewL(*this, 2000);
ss.Send(PicoMsgQuit, 0);
} else {
iCurrentLConfig.Save();
DEBUGPRINT(_L("[app] Exit (menu)"));
Exit();
}
break;
// frameskips
case EEikCmdPicoFrameskipAuto:
iCurrentConfig.iFrameskip = TPicoConfig::PFSkipAuto;
break;
case EEikCmdPicoFrameskip0:
iCurrentConfig.iFrameskip = TPicoConfig::PFSkip0;
break;
case EEikCmdPicoFrameskip1:
iCurrentConfig.iFrameskip = 1;
break;
case EEikCmdPicoFrameskip2:
iCurrentConfig.iFrameskip = 2;
break;
case EEikCmdPicoFrameskip4:
iCurrentConfig.iFrameskip = 4;
break;
case EEikCmdPicoFrameskip8:
iCurrentConfig.iFrameskip = 8;
break;
case EEikCmdPicoDebugKillEmu:
if(iGameRunner) {
iExitForcer = CExitForcer::NewL(*this, 4000);
ss.Send(PicoMsgQuit, 0);
}
break;
case EEikCmdPicoDebugInfo:
if(iGameRunner)
DisplayDebugDialogL();
break;
}
// send config update if needed
if(iCurrentConfig.iFrameskip != oldFrameskip)
SendConfig();
}
void CPicolAppUi::HandleSystemEventL(const TWsEvent& aEvent)
{
TApaSystemEvent event;
event = *(TApaSystemEvent*)aEvent.EventData();
if(event == EApaSystemEventBroughtToForeground) // application brought to foreground
{
DEBUGPRINT(_L("[app] EApaSystemEventBroughtToForeground, iEmuRunning=%i"), iEmuRunning);
// we might have missed flip open event (when moved to background),
// so make sure we have correct view active
if(iCoeEnv->ScreenDevice()->CurrentScreenMode() == EScreenModeFlipOpen) {
ActivateViewL(TVwsViewId(KUidPicolApp, KUidPicolFOView));
return;
}
}
if(event == EApaSystemEventShutdown)
{
DEBUGPRINT(_L("[app] EApaSystemEventShutdown"));
}
CEikAppUi::HandleSystemEventL(aEvent);
}
// called just before the menu is shown
void CPicolAppUi::DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane)
{
if(aResourceId == R_APP_EMU_MENU) {
TBool dimmed = !iGameRunner || !iROMLoaded;
aMenuPane->SetItemDimmed(EEikCmdPicoLoadState, dimmed);
aMenuPane->SetItemDimmed(EEikCmdPicoSaveState, dimmed);
aMenuPane->SetItemDimmed(EEikCmdPicoResume, dimmed);
aMenuPane->SetItemDimmed(EEikCmdPicoReset, dimmed);
} else if(aResourceId == R_APP_FRAMESKIP_MENU) {
TInt itemToCheck = EEikCmdPicoFrameskipAuto;
switch(iCurrentConfig.iFrameskip) {
case 0: itemToCheck = EEikCmdPicoFrameskip0; break;
case 1: itemToCheck = EEikCmdPicoFrameskip1; break;
case 2: itemToCheck = EEikCmdPicoFrameskip2; break;
case 4: itemToCheck = EEikCmdPicoFrameskip4; break;
case 8: itemToCheck = EEikCmdPicoFrameskip8; break;
}
aMenuPane->SetItemButtonState(itemToCheck, EEikMenuItemSymbolOn);
}
}
void CPicolAppUi::DisplayAboutDialogL()
{
CEikDialog* dialog = new(ELeave) CAboutDialog;
TInt iButtonRes = dialog->ExecuteLD(R_DIALOG_ABOUT);
if(iButtonRes == EEikBidYes) {
CCreditsDialog *creditsDialog = new (ELeave) CCreditsDialog();
creditsDialog->iMessageResourceID = R_TBUF_CREDITS;
creditsDialog->ExecuteLD(R_DIALOG_CREDITS);
}
}
void CPicolAppUi::DisplayOpenROMDialogL()
{
TFileName file(iCurrentLConfig.iLastROMFile);
CEikDialog* dialog = new(ELeave) CEikFileOpenDialog(&file);
//((CEikFileOpenDialog *)dialog)->SetRequiredExtension(&ext);
if(dialog->ExecuteLD(R_EIK_DIALOG_FILE_OPEN) == EEikBidOk) {
CEikonEnv::Static()->BusyMsgL(_L("Loading ROM"));
// start emu process if it is not running
if(!iGameRunner) RunGameL();
iROMLoaded = EFalse;
TBuf8<KMaxFileName> file8;
file8.Copy(file);
TAny *p[KMaxMessageArguments];
p[0]= (TAny*)(&file8);
TInt res = ss.SendReceive(PicoMsgLoadROM, &p[0]);
CEikonEnv::Static()->BusyMsgCancel();
if(res == 1)
CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to open file."));
else if(res == 2)
CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to allocate memory."));
else if(res == 3)
CEikonEnv::Static()->InfoWinL(_L("Error"), _L("The file you selected is not a game ROM."));
else if(res == 4)
CEikonEnv::Static()->InfoWinL(_L("Error"), _L("No game ROMs found in zipfile."));
else if(res == 5)
CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed while unzipping ROM."));
else if(res < 0)
CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to send request to emu process."));
else {
iROMLoaded = ETrue;
iEmuRunning = ETrue;
}
// sound errors which leave ROM loaded
if(res == 6)
CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to allocate sound buffer, disabled sound."));
else if(res == 7)
CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to start soundsystem, disabled sound."));
if(res == 6 || res == 7) iCurrentConfig.iFlags &= ~4;
iCurrentLConfig.iLastROMFile.Copy(file);
}
}
void CPicolAppUi::DisplayConfigDialogL()
{
CPicoConfigDialog* configDialog = new(ELeave)CPicoConfigDialog(iCurrentConfig, iCurrentLConfig);
configDialog->ExecuteLD(R_PICO_CONFIG);
if(iGameRunner)
SendConfig();
iCurrentLConfig.Save();
// configDialog seems to be actually destroyed later after returning,
// and this usually happens just after resuming game and causes emu slowdowns :/
iAfterConfigDialog = ETrue;
iConfigDialogClosed.UniversalTime();
}
void CPicolAppUi::DisplayDebugDialogL()
{
// first get our debug info
char dtxt[1024];
TAny *p[KMaxMessageArguments];
TPtr8 descr((TUint8*) dtxt, sizeof(dtxt));
p[0]= (TAny*)(&descr);
ss.SendReceive(PicoMsgRetrieveDebugStr, &p[0]);
CEikDialog* dialog = new(ELeave) CDebugDialog(dtxt);
dialog->ExecuteLD(R_DIALOG_DEBUG);
}
void CPicolAppUi::SendConfig()
{
// send config
if(iGameRunner) {
TAny *p[KMaxMessageArguments];
TPtrC8 descr((TUint8*) &iCurrentConfig, sizeof(iCurrentConfig));
p[0]= (TAny*)(&descr);
ss.Send(PicoMsgConfigChange, &p[0]);
}
}
// get config from emu proc
void CPicolAppUi::RetrieveConfig()
{
// ask to configure keys and receive new config
TAny *p[KMaxMessageArguments];
TPtr8 descr((TUint8*) &iCurrentConfig, sizeof(iCurrentConfig));
p[0]= (TAny*)(&descr);
ss.SendReceive(PicoMsgRetrieveConfig, &p[0]);
iCurrentLConfig.Save();
}
void CPicolAppUi::NotifyEmuDeath()
{
StopGame();
if(iQuitting) {
DEBUGPRINT(_L("[app] Exit (NotifyEmuDeath)"));
iCurrentLConfig.Save();
RProcess me;
me.Terminate(0);
}
}
void CPicolAppUi::NotifyForcedExit()
{
DEBUGPRINT(_L("[app] Exit (NotifyForcedExit)"));
StopGame();
RProcess me;
me.Terminate(0);
}
TBool CPicolAppUi::EmuRunning() const
{
return iEmuRunning;
}
void CPicolAppUi::StopGame()
{
// in case we have busyMsg and process crashes
CEikonEnv::Static()->BusyMsgCancel();
ss.Close();
if(iGameRunner) delete iGameRunner;
iGameRunner = NULL;
if(iExitForcer) delete iExitForcer;
iExitForcer = NULL;
if(iThreadWatcher1) delete iThreadWatcher1;
iThreadWatcher1 = NULL;
iROMLoaded = EFalse;
iEmuRunning = EFalse;
}
void CPicolAppUi::RunGameL()
{
TInt res = KErrNone;
// do one connection attemt to emu and ask it to quit if we succeed
res = ss.Connect();
if(res == KErrNone) {
ss.Send(PicoMsgQuit, 0);
ss.Close();
}
iGameRunner = CGameRunner::NewL(*this);
// Connect to the server
// we don't want to do complex asynchronous stuff here, so we just
// wait and do several connection attempts
User::After(200000);
for(TInt attempt=0; attempt < 10; attempt++) {
res = ss.Connect();
if(res == KErrNone) break;
User::After(200000);
}
if(res != KErrNone) {
CEikonEnv::Static()->BusyMsgCancel();
CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to communicate with the emulation process."));
StopGame();
RProcess me;
me.Terminate(2);
}
// now we are successfully connected, that means emu process' helper-communication thread is running.
// we have to keep an eye on it too, because if it crashes, symbian OS leaves it's process
// alive, but it becomes useless without it's communication thread so we have to detect it's death.
iThreadWatcher1 = CThreadWatcher::NewL(*this, KServerName);
// send initial config
SendConfig();
}
/*
void CPicolAppUi::HandleScreenDeviceChangedL()
{
// does not receive when emu is in foreground
if(iCoeEnv->ScreenDevice()->CurrentScreenMode() == 0) { // flip open
// regain focus
//iCoeEnv->BringOwnerToFront();
}
// ss.Send(PicoMsgFlipChange, 0);
}
*/
void CPicolAppUi::HandleApplicationSpecificEventL(TInt aType, const TWsEvent& aEvent)
{
DEBUGPRINT(_L("[app] event from server: %i"), aEvent.Type());
switch (aEvent.Type())
{
case EEventKeyCfgDone:
RetrieveConfig();
break;
case EEventGamePaused:
iEmuRunning = EFalse;
break;
}
}
////////////////////////////////////////////////////////////////
//
// class CEPicolAppView
//
////////////////////////////////////////////////////////////////
void CEPicolAppView::ConstructL(const TRect& aRect)
{
CreateWindowL();
SetRect(aRect);
ActivateL();
/*
* Load background image
*/
/*
TBuf<1> name = _L("*");
TRAPD(err, iBgImage = CEikonEnv::Static()->CreateBitmapL(name, EMbmEdoomDoom));
if (iBgImage)
{
iImagePosition.iX = (aRect.Size().iWidth - iBgImage->SizeInPixels().iWidth) / 2;
iImagePosition.iY = (aRect.Size().iHeight - iBgImage->SizeInPixels().iHeight) / 2;
}
*/
}
CEPicolAppView::~CEPicolAppView()
{
//if (iBgImage) delete iBgImage;
}
void CEPicolAppView::Draw(const TRect& aRect) const
{
CWindowGc& gc = SystemGc();
//if (iBgImage)
//{
// gc.DrawBitmap(iImagePosition, iBgImage);
// DrawUtils::ClearBetweenRects(gc, Rect(), TRect(iImagePosition, iBgImage->SizeInPixels()));
//}
//else
gc.Clear();//aRect);
}
////////////////////////////////////////////////////////////////
//
// class CPicolViewBase
//
////////////////////////////////////////////////////////////////
void CPicolViewBase::ViewActivatedL(const TVwsViewId& /*aPrevViewId*/, TUid /*aCustomMessageId*/, const TDesC8& /*aCustomMessage*/)
{
TPixelsAndRotation sizeAndRotation;
CEikonEnv::Static()->ScreenDevice()->GetDefaultScreenSizeAndRotation(sizeAndRotation);
CEikonEnv::Static()->ScreenDevice()->SetScreenSizeAndRotation(sizeAndRotation);
//iAppViewCtl.MakeVisible(ETrue);
}
void CPicolViewBase::ViewDeactivated()
{
//iAppViewCtl.MakeVisible(EFalse);
}
////////////////////////////////////////////////////////////////
//
// class CPicolFOView
//
////////////////////////////////////////////////////////////////
TVwsViewId CPicolFOView::ViewId() const
{
return TVwsViewId(KUidPicolApp, KUidPicolFOView);
}
TVwsViewIdAndMessage CPicolFOView::ViewScreenDeviceChangedL()
{
// only handle change to FC mode when emu process is running
if(static_cast<CPicolAppUi*>(CEikonEnv::Static()->AppUi())->EmuRunning())
return TVwsViewIdAndMessage(TVwsViewId(KUidPicolApp, KUidPicolFCView));
else return MCoeView::ViewScreenDeviceChangedL();
}
TBool CPicolFOView::ViewScreenModeCompatible(TInt aScreenMode)
{
return (aScreenMode == EScreenModeFlipOpen);
}
void CPicolFOView::ViewActivatedL(const TVwsViewId& aPrevViewId, TUid aCustomMessageId, const TDesC8& aCustomMessage)
{
DEBUGPRINT(_L("[app] FO"));
CPicolViewBase::ViewActivatedL(aPrevViewId, aCustomMessageId, aCustomMessage);
CEikonEnv::Static()->AppUiFactory()->MenuBar()->MakeVisible(ETrue);
iAppViewCtl.SetRect(static_cast<CEikAppUi*>(CEikonEnv::Static()->AppUi())->ClientRect());
}
////////////////////////////////////////////////////////////////
//
// class CPicolFCView
//
////////////////////////////////////////////////////////////////
TVwsViewId CPicolFCView::ViewId() const
{
return TVwsViewId(KUidPicolApp, KUidPicolFCView);
}
TVwsViewIdAndMessage CPicolFCView::ViewScreenDeviceChangedL()
{
return TVwsViewIdAndMessage(TVwsViewId(KUidPicolApp, KUidPicolFOView));
}
TBool CPicolFCView::ViewScreenModeCompatible(TInt aScreenMode)
{
return (aScreenMode == EScreenModeFlipClosed);
}
void CPicolFCView::ViewActivatedL(const TVwsViewId& aPrevViewId, TUid aCustomMessageId, const TDesC8& aCustomMessage)
{
DEBUGPRINT(_L("[app] FC"));
CPicolViewBase::ViewActivatedL(aPrevViewId, aCustomMessageId, aCustomMessage);
CEikonEnv::Static()->AppUiFactory()->MenuBar()->MakeVisible(EFalse);
//iAppViewCtl.ChangeLayout(ETrue);
iAppViewCtl.SetRect(CEikonEnv::Static()->ScreenDevice()->SizeInPixels());
}
////////////////////////////////////////////////////////////////
//
// framework
//
////////////////////////////////////////////////////////////////
GLDEF_C TInt E32Dll(TDllReason)
{
return KErrNone;
}
EXPORT_C CApaApplication* NewApplication()
{
return new CPicolApplication;
}
TUid CPicolApplication::AppDllUid() const
{
return KUidPicolApp;
}

View file

@ -1,178 +0,0 @@
/*******************************************************************
*
* File: App.h
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2001, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#ifndef __APP_H
#define __APP_H
#include <coecntrl.h>
#include <coeccntx.h>
#include <coemain.h>
#include <eikappui.h>
#include <eikapp.h>
#include <eikdoc.h>
#include "Engine.h"
#include "../ClientServer.h"
#include "SimpleClient.h"
#include "picodriven.hrh"
const TUid KUidPicolApp = { 0x1000C193 };
const TUid KUidPicolFOView = { 0x1000C194 };
const TUid KUidPicolFCView = { 0x1000C195 };
enum
{
EScreenModeFlipOpen = 0,
EScreenModeFlipClosed
};
//class CWsBitmap;
class CPicolDocument : public CEikDocument
{
public:
~CPicolDocument();
CPicolDocument(CEikApplication& aApp);
void ConstructL();
private: // from CEikDocument
CEikAppUi* CreateAppUiL();
};
class CEPicolAppView : public CCoeControl // , public MCoeControlBrushContext
{
public:
~CEPicolAppView();
void ConstructL(const TRect& aRect);
private:
void Draw(const TRect& aRect) const;
//CWsBitmap* iBgImage;
//TPoint iImagePosition;
};
class CPicolViewBase : public CBase, public MCoeView
{
public:
CPicolViewBase(CEPicolAppView& aAppViewCtl) : iAppViewCtl(aAppViewCtl) {}
//~CPicolViewBase();
protected:
// implements MCoeView:
virtual void ViewActivatedL(const TVwsViewId& /*aPrevViewId*/, TUid /*aCustomMessageId*/, const TDesC8& /*aCustomMessage*/);
virtual void ViewDeactivated();
//virtual void ViewConstructL();
CEPicolAppView& iAppViewCtl;
};
class CPicolFOView : public CPicolViewBase
{
public:
CPicolFOView(CEPicolAppView& aAppViewCtl) : CPicolViewBase(aAppViewCtl) {}
//~CPicolFOView();
virtual TVwsViewId ViewId() const;
virtual TVwsViewIdAndMessage ViewScreenDeviceChangedL();
virtual TBool ViewScreenModeCompatible(TInt aScreenMode);
virtual void ViewActivatedL(const TVwsViewId& /*aPrevViewId*/, TUid /*aCustomMessageId*/, const TDesC8& /*aCustomMessage*/);
};
class CPicolFCView : public CPicolViewBase
{
public:
CPicolFCView(CEPicolAppView& aAppViewCtl) : CPicolViewBase(aAppViewCtl) {}
//~CPicolFCView();
virtual TVwsViewId ViewId() const;
virtual TVwsViewIdAndMessage ViewScreenDeviceChangedL();
virtual TBool ViewScreenModeCompatible(TInt aScreenMode);
virtual void ViewActivatedL(const TVwsViewId& /*aPrevViewId*/, TUid /*aCustomMessageId*/, const TDesC8& /*aCustomMessage*/);
};
class CPicolAppUi : public CEikAppUi, public MGameWatcher
{
public:
CPicolAppUi();
void ConstructL();
~CPicolAppUi();
public: // implements MGameWatcher
void NotifyEmuDeath();
void NotifyForcedExit();
TBool EmuRunning() const;
protected: // from CEikAppUi
void HandleCommandL(TInt aCommand);
void DynInitMenuPaneL(TInt aResourceId,CEikMenuPane* aMenuPane);
void HandleSystemEventL(const TWsEvent& aEvent);
protected: // new stuf
void DisplayAboutDialogL();
void DisplayOpenROMDialogL();
void DisplayConfigDialogL();
void DisplayDebugDialogL();
void StopGame();
void RunGameL();
void SendConfig();
void RetrieveConfig();
CGameRunner* iGameRunner;
CExitForcer* iExitForcer; // makes sure emu process exits
CThreadWatcher* iThreadWatcher1; // emu process helper thread watcher
RServSession ss;
private:
//void HandleScreenDeviceChangedL();
//void HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination);
virtual void HandleApplicationSpecificEventL(TInt aType, const TWsEvent& aEvent);
private:
TBool iQuitting;
TBool iROMLoaded;
TBool iEmuRunning;
TBool iAfterConfigDialog;
TTime iConfigDialogClosed;
TPicoConfig iCurrentConfig;
TPLauncherConfig iCurrentLConfig;
CEPicolAppView* iAppView;
CPicolFOView* iFOView;
CPicolFCView* iFCView;
};
class CPicolApplication : public CEikApplication
{
private: // from CApaApplication
CApaDocument* CreateDocumentL();
TUid AppDllUid() const;
};
#endif

View file

@ -1,477 +0,0 @@
/*******************************************************************
*
* File: CSimpleTextParser.cpp
*
* Author: Peter van Sebille (peter@yipton.net)
*
* (c) Copyright 2002, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#include "CSimpleTextParser.h"
enum
{
EBadTag,
EBadZeroLengthTag,
EBadIntegerParam,
EBadAlignmentParam,
EBadRgbColorParam
};
void Panic(TInt aPanic)
{
User::Panic(_L("STP"), aPanic);
}
CSimpleTextFormatParser* CSimpleTextFormatParser::NewLC()
{
CSimpleTextFormatParser* self = new(ELeave)CSimpleTextFormatParser;
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
CSimpleTextFormatParser::~CSimpleTextFormatParser()
{
delete iParaFormat;
}
void CSimpleTextFormatParser::ConstructL()
{
iParaFormat = CParaFormat::NewL();
}
void CSimpleTextFormatParser::SetBold(TBool aEnable)
{
iCharFormat.iFontSpec.iFontStyle.SetStrokeWeight(aEnable ? EStrokeWeightBold : EStrokeWeightNormal);
iCharMask.ClearAll();
iCharMask.SetAttrib(EAttFontStrokeWeight);
iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
}
void CSimpleTextFormatParser::SetItalic(TBool aEnable)
{
iCharFormat.iFontSpec.iFontStyle.SetPosture(aEnable ? EPostureItalic : EPostureUpright);
iCharMask.ClearAll();
iCharMask.SetAttrib(EAttFontPosture);
iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
}
void CSimpleTextFormatParser::SetUnderLine(TBool aEnable)
{
iCharFormat.iFontPresentation.iUnderline = aEnable ? EUnderlineOn : EUnderlineOff;
iCharMask.ClearAll();
iCharMask.SetAttrib(EAttFontUnderline);
iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
}
void CSimpleTextFormatParser::SetHiddenText(TBool aEnable)
{
iCharFormat.iFontPresentation.iHiddenText = aEnable;
iCharMask.ClearAll();
iCharMask.SetAttrib(EAttFontHiddenText);
iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
}
TRgb CSimpleTextFormatParser::ForegroundColor()
{
iCharMask.ClearAll();
iCharMask.SetAttrib(EAttColor);
iRichText->GetCharFormat(iCharFormat, iCharMask, TextPos(), 0);
return iCharFormat.iFontPresentation.iTextColor;
}
void CSimpleTextFormatParser::SetForegroundColor(const TRgb& aColor)
{
iCharFormat.iFontPresentation.iTextColor = aColor;
iCharMask.ClearAll();
iCharMask.SetAttrib(EAttColor);
iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
}
void CSimpleTextFormatParser::SetBackgroundColor(const TRgb& aColor)
{
iParaFormat->iFillColor = aColor;
iParaMask.ClearAll();
iParaMask.SetAttrib(EAttFillColor);
iRichText->ApplyParaFormatL(iParaFormat, iParaMask, ParaPos(), 0);
}
void CSimpleTextFormatParser::NewParagraph()
{
iCurrentPara++;
iRichText->AppendParagraphL();
AppendTextL(_L(""));
}
void CSimpleTextFormatParser::SetAlignment(CParaFormat::TAlignment aAlignment)
{
iParaFormat->iHorizontalAlignment = aAlignment;
iParaMask.ClearAll();
iParaMask.SetAttrib(EAttAlignment);
iRichText->ApplyParaFormatL(iParaFormat, iParaMask, ParaPos(), 0);
}
void CSimpleTextFormatParser::SetFontHeight(TInt aHeight)
{
iCharFormat.iFontSpec.iHeight = (aHeight * KTwipsPerInch)/KPointsPerInch;
iCharMask.ClearAll();
iCharMask.SetAttrib(EAttFontHeight);
iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
}
void CSimpleTextFormatParser::SetFontName(const TDesC& aName)
{
iCharFormat.iFontSpec.iTypeface.iName = aName;
iCharFormat.iFontSpec.iTypeface.SetAttributes(0);
iCharFormat.iFontSpec.iTypeface.SetIsProportional(ETrue);
iCharMask.ClearAll();
iCharMask.SetAttrib(EAttFontTypeface);
iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
}
/*
* Character formatting:
* <b> Bold on
* </b> Bold of
* <i> Italic on
* </i> Italic off
* <u> Underline on
* </u> Underline off
* <h> Hidden text on **doesn't work**
* </h> Hidden text off **doesn't work**
* <f=name> Fontname: name (type: string)
* <s=size> Fontsize: size (type: integer)
* <fg=color> Foreground color: color (type: color)
* </fg> Restore foreground color
*
* Paragraph formatting:
* <p> New paragraph - will reset both character & paragraph formatting to defaults
* <a=align> Alignment: aling (type: alignement)
* <bg=color> Background color: color (type: color) **doesn't work**
*
* Special characters:
* </<> The character: <
*
* Types:
* - string:
* - integer: Either decimal or hexidecimal value
* - color: Either integer specifing rgb value, or (r,g,b) in which r, g and b are of type integer
* - align: element of enumeration {center, left, right}
*
* Comments:
* The syntax/parser is fairly simplistic. The parser is not trying to match a tag like
* <tag> </tag> as XML/HTML do. Basically, when it encounters a tag (e.g., <b>) it will
* simply instruct the the editor to apply the formatting from the current position as
* specified by the tag (e.g., enable bold). For example, <b><b>Hello</b>World</b> results
* in Hello displayed in a Bold font and World in a normal font.
*
* The only case where state is maintained is when using <fg=color> and </fg>. The current
* fg color is stored when parsing <fg=color> and restored when doing </fg>. Again, <fg> and
* </fg> don't have the XML/HTML <tag> </tag> behavior. For example:
* <fg=red>Peter<fg=blue>was</fg></fg>here
* results in "Peter" displayed in red, "was" displayed in blue and "here" displayed in red.
* It literally goes like this:
* 1) <fg=red> --> apply editor text color red, previous color = whatever the editor's text color is now
* 2) <fg=blue> --> apply editor text color blue, previous color = whatever the editor's text color
* is now --> red
* 3) </fg> --> apply editor text to previous color --> red
* 4) </fg> --> apply editor text to previous color --> red
*
* What you probably wanted was:
* <fg=red>Peter</fg><fg=blue>was</fg>here
* Now "Peter" is displayed in red, "was" in blue and "here" in the default editor's color
*/
static TUint32 ParseInteger(const TDesC& aString)
{
TUint32 val = 0;
TBool parsed = EFalse;
if (aString.Length() > 2)
{
if ((aString[0] == '0') && ((aString[0] == 'x') || (aString[0] == 'X')))
{
TLex lex(aString.Right(aString.Length()-2));
if (lex.Val(val, EHex) != KErrNone)
{
__ASSERT_DEBUG(ETrue, Panic(EBadIntegerParam));
}
parsed = ETrue;
}
}
if (!parsed)
{
TLex lex(aString);
if (lex.Val(val, EDecimal) != KErrNone)
{
__ASSERT_DEBUG(ETrue, Panic(EBadIntegerParam));
}
}
return val;
}
static TRgb ParseColor(const TDesC& aString)
{
if (aString.Length() > 0)
{
if (aString[0] == 'R')
{
if (aString.Compare(_L("RgbBlack")) == 0)
return KRgbBlack;
else if (aString.Compare(_L("RgbDarkGray")) == 0)
return KRgbDarkGray;
else if (aString.Compare(_L("RgbDarkRed")) == 0)
return KRgbDarkRed;
else if (aString.Compare(_L("RgbDarkGreen")) == 0)
return KRgbDarkGreen;
else if (aString.Compare(_L("RgbDarkYellow")) == 0)
return KRgbDarkYellow;
else if (aString.Compare(_L("RgbDarkBlue")) == 0)
return KRgbDarkBlue;
else if (aString.Compare(_L("RgbDarkMagenta")) == 0)
return KRgbDarkMagenta;
else if (aString.Compare(_L("RgbDarkCyan")) == 0)
return KRgbDarkCyan;
else if (aString.Compare(_L("RgbRed")) == 0)
return KRgbRed;
else if (aString.Compare(_L("RgbGreen")) == 0)
return KRgbGreen;
else if (aString.Compare(_L("RgbYellow")) == 0)
return KRgbYellow;
else if (aString.Compare(_L("RgbBlue")) == 0)
return KRgbBlue;
else if (aString.Compare(_L("RgbMagenta")) == 0)
return KRgbMagenta;
else if (aString.Compare(_L("RgbCyan")) == 0)
return KRgbCyan;
else if (aString.Compare(_L("RgbGray")) == 0)
return KRgbGray;
else if (aString.Compare(_L("RgbWhite")) == 0)
return KRgbWhite;
else
{
__ASSERT_DEBUG(ETrue, Panic(EBadRgbColorParam));
}
}
return ParseInteger(aString);
}
__ASSERT_DEBUG(ETrue, Panic(EBadRgbColorParam));
return KRgbBlack;
}
static CParaFormat::TAlignment ParseAlignment(const TDesC& aString)
{
if (aString.Compare(_L("center")) == 0)
{
return CParaFormat::ECenterAlign;
}
else if (aString.Compare(_L("left")) == 0)
{
return CParaFormat::ELeftAlign;
}
else if (aString.Compare(_L("right")) == 0)
{
return CParaFormat::ERightAlign;
}
__ASSERT_DEBUG(ETrue, Panic(EBadAlignmentParam));
return CParaFormat::ECenterAlign;
}
void CSimpleTextFormatParser::ParseTagL(const TDesC& aTag)
{
TInt tagLength = aTag.Length();
if (tagLength == 0)
{
__ASSERT_DEBUG(ETrue, Panic(EBadZeroLengthTag));
return;
}
TPtrC param(_L(""));
TInt pos = aTag.Find(_L("="));
if (pos>0)
{
param.Set(aTag.Right(aTag.Length()-pos-1));
tagLength = pos;
}
TPtrC tag = aTag.Left(tagLength);
// RDebug::Print(_L("tag=%S, param=%S"), &tag, &param);
switch (tagLength)
{
case 1:
{
if (tag.Compare(_L("a")) == 0)
SetAlignment(ParseAlignment(param));
else if (tag.Compare(_L("b")) == 0)
SetBold();
else if (tag.Compare(_L("f")) == 0)
SetFontName(param);
else if (tag.Compare(_L("h")) == 0)
SetHiddenText();
else if (tag.Compare(_L("i")) == 0)
SetItalic();
else if (tag.Compare(_L("p")) == 0)
NewParagraph();
else if (tag.Compare(_L("s")) == 0)
SetFontHeight(ParseInteger(param));
else if (tag.Compare(_L("u")) == 0)
SetUnderLine();
else
{
__ASSERT_DEBUG(ETrue, Panic(EBadTag));
}
break;
}
case 2:
{
if (tag.Compare(_L("/b")) == 0)
SetBold(EFalse);
if (tag.Compare(_L("bg")) == 0)
SetBackgroundColor(ParseColor(param));
if (tag.Compare(_L("fg")) == 0)
{
iPrevFgColor = ForegroundColor();
SetForegroundColor(ParseColor(param));
}
else if (tag.Compare(_L("/h")) == 0)
SetHiddenText(EFalse);
else if (tag.Compare(_L("/i")) == 0)
SetItalic(EFalse);
else if (tag.Compare(_L("/u")) == 0)
SetUnderLine(EFalse);
else if (tag.Compare(_L("/<")) == 0)
AppendTextL(_L("<"));
break;
}
case 3:
{
if (tag.Compare(_L("/fg")) == 0)
SetForegroundColor(iPrevFgColor);
break;
}
default:
;
}
}
void CSimpleTextFormatParser::ParseL(const TDesC& aSimpleText, CRichText& aRichText)
{
iRichText = &aRichText;
iCurrentPara = 0;
TBool done = EFalse;
TPtrC simpleText(aSimpleText);
do
{
TInt pos = simpleText.Locate('<');
if (pos > 0)
{
AppendTextL(simpleText.Left(pos));
simpleText.Set(simpleText.Right(simpleText.Length() - pos));
}
else if (pos == 0)
{
pos = simpleText.Locate('>');
if (pos<=0)
User::Leave(KErrArgument);
ParseTagL(simpleText.Mid(1, pos-1));
simpleText.Set(simpleText.Right(simpleText.Length() - pos - 1));
}
else
{
AppendTextL(simpleText);
done = ETrue;
}
} while (!done);
}
TInt CSimpleTextFormatParser::TextPos()
{
return iRichText->DocumentLength();
#if 0
TInt pos, length;
pos = iRichText->CharPosOfParagraph(length, iCurrentPara);
return pos+length-1;
#endif
}
TInt CSimpleTextFormatParser::ParaPos()
{
return TextPos();
#if 0
TInt pos, length;
pos = iRichText->CharPosOfParagraph(length, iCurrentPara);
return pos+length-1;
#endif
}
void CSimpleTextFormatParser::AppendTextL(const TDesC& aText)
{
// RDebug::Print(_L("text=%S"), &aText);
iRichText->InsertL(TextPos(), aText);
}
#if 0
void CTestDialog::ShowTextL(CRichText& aRichText)
{
aRichText.Reset();
TCharFormat charFormat;
TCharFormatMask charMask;
aRichText.GetCharFormat(charFormat, charMask, 0, 0);
TInt para = 0;
AppendTextL(_L("http://www.yipton.net"), aRichText);
para++;
aRichText.AppendParagraphL();
CParaFormat* paraFormat = CParaFormat::NewLC();
TParaFormatMask paraMask;
aRichText.GetParaFormatL(paraFormat, paraMask, ParaPos(aRichText, para), 0);
paraFormat->iHorizontalAlignment = CParaFormat::ECenterAlign;
paraMask.ClearAll();
paraMask.SetAttrib(EAttAlignment);
aRichText.ApplyParaFormatL(paraFormat, paraMask, ParaPos(aRichText, para), 0);
charFormat.iFontPresentation.iUnderline = EUnderlineOn;
charFormat.iFontSpec.iFontStyle.SetPosture(EPostureItalic);
charMask.ClearAll();
charMask.SetAttrib(EAttFontPosture);
charMask.SetAttrib(EAttFontUnderline);
aRichText.ApplyCharFormatL(charFormat, charMask, TextPos(aRichText, para));
AppendTextL(_L("mailto:Peter is here"), aRichText, para);
para++;
aRichText.AppendParagraphL();
TFontSpec fontSpec(_L("edmunds"), 20 * KPointsPerInch);
// CFont* font = NULL;
// iCoeEnv->ScreenDevice()->GetNearestFontInTwips(font, fontSpec);
charFormat.iFontSpec = fontSpec;
charMask.ClearAll();
charMask.SetAttrib(EAttFontHeight);
charMask.SetAttrib(EAttFontTypeface);
aRichText.ApplyCharFormatL(charFormat, charMask, TextPos(aRichText, para));
AppendTextL(_L("mailto:Peter is here"), aRichText, para);
CleanupStack::PopAndDestroy();
}
#endif

View file

@ -1,62 +0,0 @@
/*******************************************************************
*
* File: CSimpleTextParser.h
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2002, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#ifndef __CSIMPLE_TEXT_PARSER_H
#define __CSIMPLE_TEXT_PARSER_H
#include <e32def.h>
#include <txtrich.h> // CRichText
#include <eikrted.h> // CEikRichTextEditor
class CSimpleTextFormatParser : public CBase
{
public:
static CSimpleTextFormatParser* NewLC();
void ParseL(const TDesC& aPSTText, CRichText& aRichText);
protected:
CSimpleTextFormatParser(){}
~CSimpleTextFormatParser();
void ConstructL();
void ParseTagL(const TDesC& aTag);
TRgb ForegroundColor();
void SetBold(TBool aEnable=ETrue);
void SetItalic(TBool aEnable=ETrue);
void SetUnderLine(TBool aEnable=ETrue);
void SetFontHeight(TInt aHeight);
void SetFontName(const TDesC& aName);
void SetHiddenText(TBool aEnable=ETrue);
void SetForegroundColor(const TRgb& aColor);
void NewParagraph();
void SetAlignment(CParaFormat::TAlignment aAlignment);
void SetBackgroundColor(const TRgb& aColor);
void AppendTextL(const TDesC& aText);
TInt TextPos();
TInt ParaPos();
CRichText* iRichText;
TCharFormat iCharFormat;
TCharFormatMask iCharMask;
CParaFormat* iParaFormat;
TParaFormatMask iParaMask;
TInt iCurrentPara;
TRgb iPrevFgColor;
};
#endif /* __CSIMPLE_TEXT_PARSER_H */

View file

@ -1,473 +0,0 @@
/*******************************************************************
*
* File: Dialogs.cpp
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2002, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#include "Dialogs.h"
#include "Engine.h"
#include "picodriven.hrh"
#include "picodriven.rsg"
#include "../version.h"
#include "CSimpleTextParser.h"
#include <txtrich.h> // CRichText
#include <eikrted.h> // CEikRichTextEditor
#include <qikvertoptionbuttonlist.h> // CEikHorOptionButtonList
#include <eikopbut.h> // CEikOptionButton
#include <QuartzKeys.h> // EQuartzKeyTwoWayDown
/************************************************
*
* config Dialog
*
************************************************/
CPicoConfigDialog::CPicoConfigDialog(TPicoConfig &cfg, TPLauncherConfig &cfgl) : config(cfg), config_l(cfgl)
{
}
void CPicoConfigDialog::PostLayoutDynInitL()
{
CEikHorOptionButtonList *buttons_rot = (CEikHorOptionButtonList*) Control( ECtlOptRotation );
CEikHorOptionButtonList *buttons_disp = (CEikHorOptionButtonList*) Control( ECtlOptScreenMode );
CEikCheckBox *chkbox_altrend= (CEikCheckBox*) Control( ECtlOptUseAltRend );
CEikCheckBox *chkbox_acctmng= (CEikCheckBox*) Control( ECtlOptUseAccTiming );
CEikCheckBox *chkbox_sram = (CEikCheckBox*) Control( ECtlOptUseSRAM );
CEikCheckBox *chkbox_fps = (CEikCheckBox*) Control( ECtlOptShowFPS );
CEikCheckBox *chkbox_sound = (CEikCheckBox*) Control( ECtlOptEnableSound );
CEikCheckBox *chkbox_z80 = (CEikCheckBox*) Control( ECtlOptEmulateZ80 );
CEikCheckBox *chkbox_ym2612 = (CEikCheckBox*) Control( ECtlOptEmulateYM2612 );
CEikCheckBox *chkbox_sn76496= (CEikCheckBox*) Control( ECtlOptEmulateSN76496 );
CEikChoiceListBase *combo_sndq = (CEikChoiceListBase*) Control( ECtlOptSndQuality );
CEikCheckBox *chkbox_6bpad = (CEikCheckBox*) Control( ECtlOpt6ButtonPad );
CEikCheckBox *chkbox_gzipst = (CEikCheckBox*) Control( ECtlOptGzipStates );
CEikCheckBox *chkbox_motvol = (CEikCheckBox*) Control( ECtlOptMotDontUseVol );
CEikCheckBox *chkbox_accsprt= (CEikCheckBox*) Control( ECtlOptUseAccSprites );
CEikChoiceListBase *combo_region = (CEikChoiceListBase*) Control( ECtlOptRegion );
CEikOptionButton *opt_fit2 = (CEikOptionButton*) buttons_disp->ComponentControl( TPicoConfig::PMFit2 );
buttons_rot ->SetButtonById(ECtlOptRotation0 + config.iScreenRotation);
buttons_disp->SetButtonById(ECtlOptScreenModeCenter + config.iScreenMode);
chkbox_sram ->SetState(config.iFlags & 1 ? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_fps ->SetState(config.iFlags & 2 ? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_sound ->SetState(config.iFlags & 4 ? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_motvol ->SetState(config.iFlags & 0x40 ? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_gzipst ->SetState(config.iFlags & 0x80 ? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_z80 ->SetState(config.iPicoOpt & 4 ? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_ym2612 ->SetState(config.iPicoOpt & 1 ? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_sn76496->SetState(config.iPicoOpt & 2 ? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_altrend->SetState(config.iPicoOpt & 0x10? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_6bpad ->SetState(config.iPicoOpt & 0x20? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_acctmng->SetState(config.iPicoOpt & 0x40? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_accsprt->SetState(config.iPicoOpt & 0x80? CEikButtonBase::ESet : CEikButtonBase::EClear);
// hide "fit2" if we are not in 0 or 180 mode
if(config.iScreenRotation != TPicoConfig::PRot0 && config.iScreenRotation != TPicoConfig::PRot180) opt_fit2->MakeVisible(EFalse);
// dim some stuff for alternative renderer
if(config.iPicoOpt & 0x10) {
buttons_disp->SetDimmed(ETrue);
((CEikOptionButton*)(buttons_rot->ComponentControl(TPicoConfig::PRot0)))->SetDimmed(ETrue);
((CEikOptionButton*)(buttons_rot->ComponentControl(TPicoConfig::PRot180)))->SetDimmed(ETrue);
}
// dim accurate sprites
if(config.iPicoOpt & 0x10) {
chkbox_accsprt->SetState(CEikButtonBase::EClear);
chkbox_accsprt->SetDimmed(ETrue);
}
TInt sel = (config.iPicoOpt&8) ? 4 : 0;
sel+= (config.iFlags>>3)&3;
combo_sndq->SetCurrentItem(sel);
switch(config.PicoRegion) {
case 1: sel = 4; break;
case 2: sel = 3; break;
case 4: sel = 2; break;
case 8: sel = 1; break;
default:sel = 0; // auto
}
combo_region->SetCurrentItem(sel);
}
TBool CPicoConfigDialog::OkToExitL(TInt aButtonId)
{
if(aButtonId != EEikBidOk) return ETrue;
CEikHorOptionButtonList *buttons_rot = (CEikHorOptionButtonList*) Control( ECtlOptRotation );
CEikHorOptionButtonList *buttons_disp = (CEikHorOptionButtonList*) Control( ECtlOptScreenMode );
CEikCheckBox *chkbox_altrend= (CEikCheckBox*) Control( ECtlOptUseAltRend );
CEikCheckBox *chkbox_acctmng= (CEikCheckBox*) Control( ECtlOptUseAccTiming );
CEikCheckBox *chkbox_sram = (CEikCheckBox*) Control( ECtlOptUseSRAM );
CEikCheckBox *chkbox_fps = (CEikCheckBox*) Control( ECtlOptShowFPS );
CEikCheckBox *chkbox_sound = (CEikCheckBox*) Control( ECtlOptEnableSound );
CEikCheckBox *chkbox_z80 = (CEikCheckBox*) Control( ECtlOptEmulateZ80 );
CEikCheckBox *chkbox_ym2612 = (CEikCheckBox*) Control( ECtlOptEmulateYM2612 );
CEikCheckBox *chkbox_sn76496= (CEikCheckBox*) Control( ECtlOptEmulateSN76496 );
CEikChoiceListBase *combo_sndq = (CEikChoiceListBase*) Control( ECtlOptSndQuality );
CEikCheckBox *chkbox_6bpad = (CEikCheckBox*) Control( ECtlOpt6ButtonPad );
CEikCheckBox *chkbox_gzipst = (CEikCheckBox*) Control( ECtlOptGzipStates );
CEikCheckBox *chkbox_motvol = (CEikCheckBox*) Control( ECtlOptMotDontUseVol );
CEikCheckBox *chkbox_accsprt= (CEikCheckBox*) Control( ECtlOptUseAccSprites );
CEikChoiceListBase *combo_region = (CEikChoiceListBase*) Control( ECtlOptRegion );
config.iScreenRotation = (TPicoConfig::TPicoScreenRotation) (buttons_rot->LabeledButtonId() - ECtlOptRotation0);
config.iScreenMode = (TPicoConfig::TPicoScreenMode) (buttons_disp->LabeledButtonId() - ECtlOptScreenModeCenter);
if(chkbox_sram ->State() == CEikButtonBase::ESet) config.iFlags |= 1; else config.iFlags &= ~1;
if(chkbox_fps ->State() == CEikButtonBase::ESet) config.iFlags |= 2; else config.iFlags &= ~2;
if(chkbox_sound ->State() == CEikButtonBase::ESet) config.iFlags |= 4; else config.iFlags &= ~4;
if(chkbox_motvol ->State() == CEikButtonBase::ESet) config.iFlags |= 0x40; else config.iFlags &= ~0x40;
if(chkbox_gzipst ->State() == CEikButtonBase::ESet) config.iFlags |= 0x80; else config.iFlags &= ~0x80;
if(chkbox_z80 ->State() == CEikButtonBase::ESet) config.iPicoOpt |= 4; else config.iPicoOpt &= ~4;
if(chkbox_ym2612 ->State() == CEikButtonBase::ESet) config.iPicoOpt |= 1; else config.iPicoOpt &= ~1;
if(chkbox_sn76496->State() == CEikButtonBase::ESet) config.iPicoOpt |= 2; else config.iPicoOpt &= ~2;
if(chkbox_altrend->State() == CEikButtonBase::ESet) config.iPicoOpt |= 0x10;else config.iPicoOpt &= ~0x10;
if(chkbox_6bpad ->State() == CEikButtonBase::ESet) config.iPicoOpt |= 0x20;else config.iPicoOpt &= ~0x20;
if(chkbox_acctmng->State() == CEikButtonBase::ESet) config.iPicoOpt |= 0x40;else config.iPicoOpt &= ~0x40;
if(chkbox_accsprt->State() == CEikButtonBase::ESet) config.iPicoOpt |= 0x80;else config.iPicoOpt &= ~0x80;
TInt sel = combo_sndq->CurrentItem();
if(sel > 3) { config.iPicoOpt |= 8; sel-=4; } else config.iPicoOpt &= ~8;
config.iFlags &= ~0x18;
config.iFlags |= (sel<<3)&0x18;
switch(combo_region->CurrentItem()) {
case 4: config.PicoRegion = 1; break;
case 3: config.PicoRegion = 2; break;
case 2: config.PicoRegion = 4; break;
case 1: config.PicoRegion = 8; break;
default:config.PicoRegion = 0; // auto
}
return ETrue;
}
// simple GUI stuff needs lots of code
void CPicoConfigDialog::HandleControlStateChangeL(TInt aControlId)
{
if(aControlId == ECtlOptEnableSound) {
CEikCheckBox *chkbox_sound = (CEikCheckBox*) Control( ECtlOptEnableSound );
CEikCheckBox *chkbox_z80 = (CEikCheckBox*) Control( ECtlOptEmulateZ80 );
CEikCheckBox *chkbox_ym2612 = (CEikCheckBox*) Control( ECtlOptEmulateYM2612 );
CEikCheckBox *chkbox_sn76496= (CEikCheckBox*) Control( ECtlOptEmulateSN76496 );
if(chkbox_sound->State() == CEikButtonBase::ESet) {
// check all sound chips too, but only if they all are not set
if((chkbox_z80->State() | chkbox_ym2612->State() | chkbox_sn76496->State()) == CEikButtonBase::EClear) { // (==0)
chkbox_z80 ->SetState(CEikButtonBase::ESet);
chkbox_ym2612 ->SetState(CEikButtonBase::ESet);
chkbox_sn76496->SetState(CEikButtonBase::ESet);
chkbox_z80 ->DrawDeferred();
chkbox_ym2612 ->DrawDeferred();
chkbox_sn76496->DrawDeferred();
}
} else {
// clear everything, but only if everything is set
if((chkbox_z80->State() & chkbox_ym2612->State() & chkbox_sn76496->State()) == CEikButtonBase::ESet) { // (==1)
chkbox_z80 ->SetState(CEikButtonBase::EClear);
chkbox_ym2612 ->SetState(CEikButtonBase::EClear);
chkbox_sn76496->SetState(CEikButtonBase::EClear);
chkbox_z80 ->DrawDeferred();
chkbox_ym2612 ->DrawDeferred();
chkbox_sn76496->DrawDeferred();
}
}
} else if(aControlId == ECtlOptUseAltRend) {
CEikCheckBox *chkbox_altrend= (CEikCheckBox*) Control( ECtlOptUseAltRend );
CEikCheckBox *chkbox_accsprt= (CEikCheckBox*) Control( ECtlOptUseAccSprites );
CEikHorOptionButtonList *buttons_rot = (CEikHorOptionButtonList*) Control( ECtlOptRotation );
CEikHorOptionButtonList *buttons_disp = (CEikHorOptionButtonList*) Control( ECtlOptScreenMode );
TBool dimmed = chkbox_altrend->State() == CEikButtonBase::ESet;
// show/hide more stuff for alternative renderer
buttons_disp->SetDimmed(dimmed);
chkbox_accsprt->SetDimmed(dimmed);
((CEikOptionButton*)(buttons_rot->ComponentControl(TPicoConfig::PRot0)))->SetDimmed(dimmed);
((CEikOptionButton*)(buttons_rot->ComponentControl(TPicoConfig::PRot180)))->SetDimmed(dimmed);
if(dimmed && buttons_rot->LabeledButtonId() != ECtlOptRotation90 && buttons_rot->LabeledButtonId() != ECtlOptRotation270) {
buttons_rot->SetButtonById(ECtlOptRotation90);
aControlId = ECtlOptRotation; // cause rotation update
}
buttons_disp->SetButtonById(ECtlOptScreenModeCenter);
chkbox_accsprt->DrawDeferred();
buttons_disp->DrawDeferred();
buttons_rot->DrawDeferred();
}
if(aControlId == ECtlOptRotation) {
CEikHorOptionButtonList *buttons_rot = (CEikHorOptionButtonList*) Control( ECtlOptRotation );
CEikHorOptionButtonList *buttons_disp = (CEikHorOptionButtonList*) Control( ECtlOptScreenMode );
CEikOptionButton *opt_fit2 = (CEikOptionButton*) buttons_disp->ComponentControl( TPicoConfig::PMFit2 );
if(buttons_rot->LabeledButtonId() == ECtlOptRotation0 || buttons_rot->LabeledButtonId() == ECtlOptRotation180) {
opt_fit2->MakeVisible(ETrue);
opt_fit2->DrawDeferred();
} else {
if(opt_fit2->State() == CEikButtonBase::ESet) {
buttons_disp->SetButtonById(ECtlOptScreenModeFit);
buttons_disp->DrawDeferred();
}
opt_fit2->MakeVisible(EFalse);
}
}
}
/*************************************************************
*
* Credits dialog
*
**************************************************************/
void CCreditsDialog::PreLayoutDynInitL()
{
CDesCArrayFlat* desArray = CEikonEnv::Static()->ReadDesCArrayResourceL(iMessageResourceID);
CleanupStack::PushL(desArray);
TInt iLength;
TInt count = desArray->Count();
for (TInt i=0 ;i < count; i++)
{
iLength = static_cast<CEikGlobalTextEditor*>(Control(ECtlCredits))->TextLength();
static_cast<CEikGlobalTextEditor*>(Control(ECtlCredits))->Text()->InsertL(iLength, desArray->operator[](i));
iLength = static_cast<CEikGlobalTextEditor*>(Control(ECtlCredits))->TextLength();
static_cast<CEikGlobalTextEditor*>(Control(ECtlCredits))->Text()->InsertL(iLength, CEditableText::ELineBreak);
}
CleanupStack::PopAndDestroy(desArray);
}
void CCreditsDialog::PostLayoutDynInitL()
{
static_cast<CEikGlobalTextEditor*>(Control(ECtlCredits))->CreateScrollBarFrameL();
static_cast<CEikGlobalTextEditor*>(Control(ECtlCredits))->ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EAuto, CEikScrollBarFrame::EAuto);
}
TKeyResponse CCreditsDialog::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
if (aType == EEventKey)
{
if (aKeyEvent.iCode == EQuartzKeyTwoWayDown)
{
static_cast<CEikGlobalTextEditor*>(Control(ECtlCredits))->MoveDisplayL(TCursorPosition::EFLineDown);
static_cast<CEikGlobalTextEditor*>(Control(ECtlCredits))->UpdateScrollBarsL();
return EKeyWasConsumed;
}
else if (aKeyEvent.iCode == EQuartzKeyTwoWayUp)
{
static_cast<CEikGlobalTextEditor*>(Control(ECtlCredits))->MoveDisplayL(TCursorPosition::EFLineUp);
static_cast<CEikGlobalTextEditor*>(Control(ECtlCredits))->UpdateScrollBarsL();
return EKeyWasConsumed;
}
}
return CEikDialog::OfferKeyEventL(aKeyEvent, aType);
}
/*************************************************************
*
* Debug dialog
*
**************************************************************/
CDebugDialog::CDebugDialog(char *t)
{
Mem::Copy(iText, t, 1024);
iText[1023] = 0;
}
void CDebugDialog::PreLayoutDynInitL()
{
char *p = iText, *line = iText;
TBool end=0;
TBuf<128> tbuf;
CEikGlobalTextEditor *editor = static_cast<CEikGlobalTextEditor*>(Control(ECtlDebugEdit));
while(!end) {
while(*p && *p != '\r' && *p != '\n') p++;
if(!*p) end=1;
*p = 0;
TPtrC8 ptr((TUint8*) line);
tbuf.Copy(ptr);
editor->Text()->InsertL(editor->TextLength(), tbuf);
editor->Text()->InsertL(editor->TextLength(), CEditableText::ELineBreak);
line = ++p;
}
}
void CDebugDialog::PostLayoutDynInitL()
{
static_cast<CEikGlobalTextEditor*>(Control(ECtlDebugEdit))->CreateScrollBarFrameL();
static_cast<CEikGlobalTextEditor*>(Control(ECtlDebugEdit))->ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EAuto, CEikScrollBarFrame::EAuto);
}
TKeyResponse CDebugDialog::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
if (aType == EEventKey)
{
if (aKeyEvent.iCode == EQuartzKeyTwoWayDown)
{
static_cast<CEikGlobalTextEditor*>(Control(ECtlDebugEdit))->MoveDisplayL(TCursorPosition::EFLineDown);
static_cast<CEikGlobalTextEditor*>(Control(ECtlDebugEdit))->UpdateScrollBarsL();
return EKeyWasConsumed;
}
else if (aKeyEvent.iCode == EQuartzKeyTwoWayUp)
{
static_cast<CEikGlobalTextEditor*>(Control(ECtlDebugEdit))->MoveDisplayL(TCursorPosition::EFLineUp);
static_cast<CEikGlobalTextEditor*>(Control(ECtlDebugEdit))->UpdateScrollBarsL();
return EKeyWasConsumed;
}
}
return CEikDialog::OfferKeyEventL(aKeyEvent, aType);
}
/************************************************
*
* SimpleTextInfoDialog
*
************************************************/
CSimpleTextInfoDialog::CSimpleTextInfoDialog(TInt aTextIdOne, TInt aRichTextCtlIdOne, TInt aTextIdTwo, TInt aRichTextCtlIdTwo, TBool aSimpleTextResIdOneIsArray, TBool aSimpleTextResIdTwoIsArray)
: iSimpleTextResIdOne(aTextIdOne),
iSimpleTextResIdTwo(aTextIdTwo),
iRichTextCtlIdOne(aRichTextCtlIdOne),
iRichTextCtlIdTwo(aRichTextCtlIdTwo),
iSimpleTextResIdOneIsArray(aSimpleTextResIdOneIsArray),
iSimpleTextResIdTwoIsArray(aSimpleTextResIdTwoIsArray),
iSetDialogBackground(ETrue)
{
}
void CSimpleTextInfoDialog::PreLayoutDynInitL()
{
CEikRichTextEditor* richTextEditor;
if (iRichTextCtlIdOne != -1)
{
richTextEditor=STATIC_CAST(CEikRichTextEditor*, Control(iRichTextCtlIdOne));
PreLayoutDynInitRichTextL(*richTextEditor, iRichTextCtlIdOne, iSimpleTextResIdOne);
}
if (iRichTextCtlIdTwo != -1)
{
richTextEditor=STATIC_CAST(CEikRichTextEditor*, Control(iRichTextCtlIdTwo));
richTextEditor->Border().SetType(ENone);
PreLayoutDynInitRichTextL(*richTextEditor, iRichTextCtlIdTwo, iSimpleTextResIdTwo);
}
}
void CSimpleTextInfoDialog::PreLayoutDynInitRichTextL(CEikRichTextEditor& aRichTextEditor, TInt aRichTextCtlId, TInt aSimpleTextResId)
{
iEikonEnv->BusyMsgL(_L("Opening"));
aRichTextEditor.SetEdwinSizeObserver(this);
if (iSetDialogBackground)
aRichTextEditor.SetBackgroundColorL(iEikonEnv->Color(EColorDialogBackground));
aRichTextEditor.SetSize(aRichTextEditor.Size()); // Set the size of the edwin
// no scrollbars for us
aRichTextEditor.CreateScrollBarFrameL(); // Create the scrollbars
aRichTextEditor.ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff, iWantVertScrollbar ? CEikScrollBarFrame::EAuto: CEikScrollBarFrame::EOff);
ShowTextL(*aRichTextEditor.RichText(), aRichTextCtlId, aSimpleTextResId);
aRichTextEditor.UpdateAllFieldsL(); // Updates all the fields in the document
aRichTextEditor.UpdateScrollBarsL();
}
void CSimpleTextInfoDialog::PostLayoutDynInitL()
{
Layout();
iEikonEnv->BusyMsgCancel();
}
TBool CSimpleTextInfoDialog::HandleEdwinSizeEventL(CEikEdwin* aEdwin, TEdwinSizeEvent aEventType, TSize aDesirableEdwinSize)
{
if ((aEventType == EEventSizeChanging))
aEdwin->SetSize(aDesirableEdwinSize);
return EFalse;
}
void CSimpleTextInfoDialog::ShowTextL(CRichText& aRichText, TInt /*aRichTextCtlId*/, TInt aResId)
{
if (aResId != -1)
{
if ( ((aResId == iSimpleTextResIdOne) && (iSimpleTextResIdOneIsArray)) ||
((aResId == iSimpleTextResIdTwo) && (iSimpleTextResIdTwoIsArray))
)
{
CDesCArrayFlat* desArray = CEikonEnv::Static()->ReadDesCArrayResourceL(aResId);
CleanupStack::PushL(desArray);
CSimpleTextFormatParser* parser = CSimpleTextFormatParser::NewLC();
TInt count = desArray->Count();
for (TInt i=0 ;i<count ; i++)
parser->ParseL(desArray->operator[](i), aRichText);
CleanupStack::PopAndDestroy(parser);
CleanupStack::PopAndDestroy(desArray);
}
else
{
HBufC* text = CEikonEnv::Static()->AllocReadResourceLC(aResId);
ShowSimpleTextL(*text, aRichText);
CleanupStack::PopAndDestroy(text);
}
}
}
void CSimpleTextInfoDialog::ShowSimpleTextL(const TDesC& aSimpleText, CRichText& aRichText)
{
CSimpleTextFormatParser* parser = CSimpleTextFormatParser::NewLC();
parser->ParseL(aSimpleText, aRichText);
CleanupStack::PopAndDestroy(parser);
}
/************************************************
*
* About Dialog
*
************************************************/
CAboutDialog::CAboutDialog() : CSimpleTextInfoDialog(-1, ECtlAboutVersion, R_SIMPLE_TEXT_ABOUT_LINKS, ECtlAboutLinks)
{
}
void CAboutDialog::ShowTextL(CRichText& aRichText, TInt aRichTextCtlId, TInt aResId)
{
if (aRichTextCtlId == ECtlAboutLinks)
CSimpleTextInfoDialog::ShowTextL(aRichText, aRichTextCtlId, aResId);
else
{
TBuf<16> versionText;
TBuf<512> text;
#if (KPicoBuildNumber != 0)
versionText.Format(_L("%d.%d%d"), KPicoMajorVersionNumber, KPicoMinorVersionNumber, KPicoBuildNumber);
#else
versionText.Format(_L("%d.%d"), KPicoMajorVersionNumber, KPicoMinorVersionNumber);
#endif
HBufC* aboutFormat = CEikonEnv::Static()->AllocReadResourceLC(R_SIMPLE_TEXT_ABOUT);
text.Format(*aboutFormat, &versionText);
ShowSimpleTextL(text, aRichText);
CleanupStack::PopAndDestroy(aboutFormat);
}
}

View file

@ -1,145 +0,0 @@
/*******************************************************************
*
* File: Dialogs.h
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2002, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#ifndef __DIALOGS_H
#define __DIALOGS_H
#include <eikenv.h>
#include <eikdialg.h>
#include <eiktxlbx.h>
#include <eiktxlbm.h>
#include <eikdlgtb.h>
#include <eiklabel.h>
#include <eikchlst.h>
#include <eikchkbx.h>
#include <eikedwob.h>
#include "../ClientServer.h"
class CRichText;
class CEikRichTextEditor;
class TPLauncherConfig;
/************************************************
*
* CSimpleTextInfo Dialog
*
************************************************/
class CSimpleTextInfoDialog : public CEikDialog, public MEikEdwinSizeObserver
{
public:
CSimpleTextInfoDialog(TInt aTextIdOne = -1, TInt aRichTextCtlIdOne = -1,
TInt aTextIdTwo = -1, TInt aRichTextCtlIdTwo = -1,
TBool aSimpleTextResIdOneIsArray = EFalse, TBool aSimpleTextResIdTwoIsArray = EFalse
);
void SetDialogBackground(TBool aEnable){iSetDialogBackground=aEnable;}
void WantVertScrollbar(TBool aEnable){iWantVertScrollbar=aEnable;}
public: // implements MEikEdwinSizeObserver
virtual TBool HandleEdwinSizeEventL(CEikEdwin* aEdwin, TEdwinSizeEvent aEventType, TSize aDesirableEdwinSize);
protected: // framework
void PreLayoutDynInitL();
void PostLayoutDynInitL();
protected: // new stuff
virtual void ShowTextL(CRichText& aRichText, TInt aRichTextCtlId, TInt aResId);
virtual void PreLayoutDynInitRichTextL(CEikRichTextEditor& aRichTextEditor, TInt aRichTextCtlId, TInt aResId);
void ShowSimpleTextL(const TDesC& aSimpleText, CRichText& aRichText);
TInt iSimpleTextResIdOne;
TInt iSimpleTextResIdTwo;
TInt iRichTextCtlIdOne;
TInt iRichTextCtlIdTwo;
TBool iSimpleTextResIdOneIsArray;
TBool iSimpleTextResIdTwoIsArray;
TBool iSetDialogBackground;
TBool iWantVertScrollbar;
};
/************************************************
*
* config Dialog
*
************************************************/
class CPicoConfigDialog : public CEikDialog
{
public:
CPicoConfigDialog(TPicoConfig &cfg, TPLauncherConfig &cfgl);
protected: // framework
void PostLayoutDynInitL();
void HandleControlStateChangeL(TInt aControlId);
TBool OkToExitL(TInt aButtonId);
TPicoConfig &config;
TPLauncherConfig &config_l;
};
/************************************************
*
* About Dialog
*
************************************************/
class CAboutDialog : public CSimpleTextInfoDialog
{
public:
CAboutDialog();
protected: // from CSimpleTextInfoDialog
virtual void ShowTextL(CRichText& aRichText, TInt aRichTextCtlId, TInt aResId);
};
/*************************************************************
*
* Credits dialog
*
**************************************************************/
class CCreditsDialog : public CEikDialog
{
public:
TInt iMessageResourceID;
protected:
void PreLayoutDynInitL();
void PostLayoutDynInitL();
TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
};
/*************************************************************
*
* Debug dialog
*
**************************************************************/
class CDebugDialog : public CEikDialog
{
public:
CDebugDialog(char *t);
protected:
char iText[1024];
void PreLayoutDynInitL();
void PostLayoutDynInitL();
TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
};
#endif // __DIALOGS_H

View file

@ -1,256 +0,0 @@
/*******************************************************************
*
* File: Engine.cpp
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2002, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#include "Engine.h"
#include <w32std.h>
#include <eikenv.h>
//#include <eikdll.h>
#include "../version.h"
CGameRunner::~CGameRunner()
{
Cancel();
RProcess process;
if(process.Open(iProcessId) == KErrNone) {
process.Terminate(1);
process.Close();
}
}
CGameRunner::CGameRunner(MGameWatcher& aGameWatcher)
: CActive(CActive::EPriorityStandard), iGameWatcher(aGameWatcher)
{
}
CGameRunner* CGameRunner::NewL(MGameWatcher& aGameWatcher)
{
CGameRunner* self = new(ELeave) CGameRunner(aGameWatcher);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(); // self
return self;
}
void CGameRunner::ConstructL()
{
RProcess newProcess, thisProcess;
// make path to picosmall
TBuf<KMaxFileName> exePath;
TBuf<KMaxFileName*3> tmpbuff; // hopefully large enough
thisProcess.CommandLine(tmpbuff);
TInt pos = tmpbuff.Find(_L(" "));
if(pos == KErrNotFound) pos = tmpbuff.Length();
for(pos--; pos > 2; pos--)
if(tmpbuff[pos] == '\\') break;
if(pos > 2) {
exePath.Copy(tmpbuff.Ptr(), pos+1);
exePath.Append(_L("PICOSMALL.EXE"));
}
DEBUGPRINT(_L("[app] starting EXE: %S"), &exePath);
if(newProcess.Create(exePath, _L(""))) {
CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to start emulation process."));
thisProcess.Terminate(1);
}
iProcessId = newProcess.Id();
DEBUGPRINT(_L("[app] newProcess.Id(): %d"), iProcessId);
CActiveScheduler::Add(this);
newProcess.SetOwner(thisProcess); // Warning: phone strangely reboots when attempting to get owner after thisProcess exits
newProcess.Logon(iStatus);
SetActive();
newProcess.Resume(); // start execution
newProcess.Close();
}
void CGameRunner::RunL()
{
iGameWatcher.NotifyEmuDeath();
}
void CGameRunner::DoCancel()
{
RProcess process;
if(process.Open(iProcessId) == KErrNone) {
process.LogonCancel(iStatus);
process.Close();
}
}
// CExitForcer
CExitForcer::~CExitForcer()
{
Cancel();
}
CExitForcer::CExitForcer(MGameWatcher& aGameWatcher) : CActive(CActive::EPriorityStandard), iGameWatcher(aGameWatcher)
{
}
CExitForcer* CExitForcer::NewL(MGameWatcher& aGameWatcher, TInt ms)
{
CExitForcer* self = new(ELeave) CExitForcer(aGameWatcher);
CleanupStack::PushL(self);
self->ConstructL(ms);
CleanupStack::Pop(); // self
return self;
}
void CExitForcer::ConstructL(TInt ms)
{
CActiveScheduler::Add(this);
iTimer.CreateLocal();
iTimer.After(iStatus, ms*1000);
SetActive();
}
void CExitForcer::RunL()
{
iGameWatcher.NotifyForcedExit();
}
void CExitForcer::DoCancel()
{
if(iTimer.Handle()) {
iTimer.Cancel();
iTimer.Close();
}
}
// CThreadWatcher
CThreadWatcher::~CThreadWatcher()
{
Cancel();
}
CThreadWatcher::CThreadWatcher(MGameWatcher& aGameWatcher, const TDesC& aName)
: CActive(CActive::EPriorityStandard), iGameWatcher(aGameWatcher), iName(aName)
{
}
CThreadWatcher* CThreadWatcher::NewL(MGameWatcher& aGameWatcher, const TDesC& aName)
{
CThreadWatcher* self = new(ELeave) CThreadWatcher(aGameWatcher, aName);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(); // self
return self;
}
void CThreadWatcher::ConstructL()
{
CActiveScheduler::Add(this);
RThread thread;
if(thread.Open(iName) == KErrNone) {
thread.Logon(iStatus);
thread.Close();
SetActive();
}
}
void CThreadWatcher::RunL()
{
iGameWatcher.NotifyEmuDeath();
}
void CThreadWatcher::DoCancel()
{
RThread thread;
if(thread.Open(iName) == KErrNone) {
thread.LogonCancel(iStatus);
thread.Close();
}
}
// config
TPLauncherConfig::TPLauncherConfig(TPicoConfig &cfg)
: iEmuConfig(cfg)
{
iLastROMFile.Copy(_L("C:\\"));
// ini
TBuf<KMaxFileName*3> tmpbuff; // hopefully large enough
RProcess me;
me.CommandLine(tmpbuff);
TInt pos = tmpbuff.Find(_L(" "));
if(pos == KErrNotFound) pos = tmpbuff.Length();
if(pos > 3) {
iIniFileName.Copy(tmpbuff.Ptr(), pos-3);
iIniFileName.Append(_L("ini"));
}
//DEBUGPRINT(_L("[app] made ini: %S"), &iIniFileName);
}
void TPLauncherConfig::Load()
{
RFile file;
if(!file.Open(CEikonEnv::Static()->FsSession(), iIniFileName, 0))
{
TInt version;
TPckg<TInt> pkg_version(version);
TPckg<TBool> pkg_Pad(iPad);
TBuf8<KMaxFileName> pad0; // reserved for future use (6 words)
TPtr8 picoCfg((TUint8*) &iEmuConfig, sizeof(iEmuConfig));
file.Read(pkg_version);
file.Read(pkg_Pad);
file.Read(pad0, 24);
file.Read(pad0, KMaxFileName);
file.Read(picoCfg);
TBuf8<KMaxFileName> file8(pad0.Ptr()); // take as zero terminated string
iLastROMFile.Copy(file8);
//DEBUGPRINT(_L("[app] iLastROMFile (%i): %S"), iLastROMFile.Length(), &iLastROMFile);
file.Close();
}
}
void TPLauncherConfig::Save()
{
RFile file;
if(!file.Replace(CEikonEnv::Static()->FsSession(), iIniFileName, EFileWrite)) {
TInt version = (KPicoMajorVersionNumber<<24)+(KPicoMinorVersionNumber<<16);
TPckgC<TInt> pkg_version(version);
TPckgC<TBool> pkg_Pad(iPad);
TBuf8<KMaxFileName> pad0; pad0.FillZ(KMaxFileName);
TBuf8<KMaxFileName> file8; file8.Copy(iLastROMFile);
TPtrC8 picoCfg((TUint8*) &iEmuConfig, sizeof(iEmuConfig));
file.Write(pkg_version);
file.Write(pkg_Pad); // 0x0004
file.Write(pad0, 24); // 0x0008, reserved for future use (6 words)
file.Write(file8); // 0x0020
file.Write(pad0, KMaxFileName-file8.Length());
file.Write(picoCfg); // 0x0120
file.Close();
}
}

View file

@ -1,112 +0,0 @@
/*******************************************************************
*
* File: Engine.h
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2002, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#ifndef __ENGINE_H
#define __ENGINE_H
#include <e32base.h>
#include <etel.h>
#include "../ClientServer.h"
class RFs;
#ifdef __DEBUG_PRINT
#define DEBUGPRINT(x...) RDebug::Print(x)
#else
#define DEBUGPRINT(x...)
#endif
class MGameWatcher
{
public:
virtual void NotifyEmuDeath() = 0;
virtual void NotifyForcedExit() = 0;
};
class CGameRunner : public CActive
{
public:
static CGameRunner* NewL(MGameWatcher& aGameWatcher);
~CGameRunner();
void KillAfter(TInt ms);
protected:
CGameRunner(MGameWatcher& aGameWatcher);
void ConstructL();
virtual void RunL();
virtual void DoCancel();
MGameWatcher& iGameWatcher;
TProcessId iProcessId;
};
class CExitForcer : public CActive
{
public:
static CExitForcer* NewL(MGameWatcher& aGameWatcher, TInt ms);
~CExitForcer();
protected:
CExitForcer(MGameWatcher& aGameWatcher);
void ConstructL(TInt ms);
virtual void RunL();
virtual void DoCancel();
MGameWatcher& iGameWatcher;
RTimer iTimer;
};
class CThreadWatcher : public CActive
{
public:
static CThreadWatcher* NewL(MGameWatcher& aGameWatcher, const TDesC& aName);
~CThreadWatcher();
protected:
CThreadWatcher(MGameWatcher& aGameWatcher, const TDesC& aName);
void ConstructL();
virtual void RunL();
virtual void DoCancel();
MGameWatcher& iGameWatcher;
const TDesC& iName; // thread name
};
// configuration emu process doesn't care about
class TPLauncherConfig {
public:
TPLauncherConfig(TPicoConfig &cfg);
void Load();
void Save();
TBool iPad; // was iPauseOnCall
TFileName iLastROMFile;
TPicoConfig &iEmuConfig;
private:
TFileName iIniFileName;
};
#endif

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,016 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,014 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -1,70 +0,0 @@
enum TAppMenuCommands
{
// Emu menu
EEikCmdPicoLoadState = 10000,
EEikCmdPicoSaveState,
EEikCmdPicoLoadROM,
EEikCmdPicoResume,
EEikCmdPicoReset,
EEikCmdPicoKeys,
EEikCmdPicoSettings,
// Frameskip menu
EEikCmdPicoFrameskipAuto,
EEikCmdPicoFrameskip0,
EEikCmdPicoFrameskip1,
EEikCmdPicoFrameskip2,
EEikCmdPicoFrameskip4,
EEikCmdPicoFrameskip8,
// Debug menu
EEikCmdPicoDebugKillEmu,
EEikCmdPicoDebugInfo,
// config Dialog
// pages
ECtlOptPageMain,
ECtlOptPageSound,
ECtlOptPageMisc,
// main page
ECtlOptRotationLabel,
ECtlOptRotation,
ECtlOptRotation0,
ECtlOptRotation90,
ECtlOptRotation180,
ECtlOptRotation270,
ECtlOptScreenModeLabel,
ECtlOptScreenMode,
ECtlOptScreenModeCenter,
ECtlOptScreenModeFit,
ECtlOptScreenModeFit2,
ECtlOptUseAltRend,
ECtlOptUseAccTiming,
ECtlOptUseAccSprites,
ECtlOptShowFPS,
// sound page
ECtlOptEnableSound,
ECtlOptChipSelLabel,
ECtlOptEmulateZ80,
ECtlOptEmulateYM2612,
ECtlOptEmulateSN76496,
ECtlOptSndQLabel,
ECtlOptSndQuality,
// misc page
ECtlOpt6ButtonPad,
ECtlOptGzipStates,
ECtlOptUseSRAM,
ECtlOptMotDontUseVol,
ECtlOptRegionLabel,
ECtlOptRegion,
// credits
ECtlCredits,
// debug
ECtlDebugEdit
};
#define ECtlAboutVersion 1
#define ECtlAboutLinks 2

View file

@ -1,34 +0,0 @@
TARGET PicodriveN.app
TARGETTYPE app
TARGETPATH \system\Apps\PicodriveN
UID 0x100039CE 0x1000C193
USERINCLUDE .
SYSTEMINCLUDE \epoc32\include
SOURCEPATH .
SOURCE App.cpp
SOURCE Engine.cpp
SOURCE Dialogs.cpp
SOURCE CSimpleTextParser.cpp
SOURCE SimpleClient.cpp
LIBRARY EUSER.LIB WS32.LIB EFSRV.LIB
LIBRARY APPARC.LIB CONE.LIB
LIBRARY EIKCOCTL.LIB EIKCORE.LIB EIKDLG.LIB EIKCTL.LIB
LIBRARY EIKFILE.LIB // CEikFileOpenDialog
LIBRARY EGUL.LIB // CColorList
LIBRARY ETEXT.LIB // TCharFormat
LIBRARY GDI.LIB // TTypeface
//LIBRARY ETEL.LIB
//LIBRARY APGRFX.LIB FBSCLI.LIB bafl.lib BITGDI.LIB
SOURCEPATH .
RESOURCE PicodriveN.rss
//MACRO __DEBUG_PRINT
AIF PicodriveN.aif . PicodriveNAif.rss c8 PicoN20x16.bmp PicoN20x16m.bmp PicoN32x32.bmp PicoN32x32m.bmp

View file

@ -1,474 +0,0 @@
NAME PDN
#include <eikon.rh>
#include <eikon.rsg>
#include "picodriven.hrh"
RESOURCE RSS_SIGNATURE { }
RESOURCE TBUF { buf=""; }
RESOURCE EIK_APP_INFO
{
menubar=r_app_menubar;
hotkeys=r_app_hotkeys;
}
RESOURCE HOTKEYS r_app_hotkeys
{
control=
{
HOTKEY { command=EEikCmdExit; key='e'; }
};
}
RESOURCE MENU_BAR r_app_menubar
{
titles=
{
MENU_TITLE { menu_pane=r_app_emu_menu; txt="Emu"; },
MENU_TITLE { menu_pane=r_app_frameskip_menu; txt="Frameskip"; }
#ifdef __DEBUG_PRINT
,MENU_TITLE { menu_pane=r_app_debug_menu; txt="Debug"; }
#endif
};
}
RESOURCE MENU_PANE r_app_emu_menu
{
items=
{
MENU_ITEM { command=EEikCmdPicoLoadState; txt="Load state"; flags=EEikMenuItemDimmed; },
MENU_ITEM { command=EEikCmdPicoSaveState; txt="Save state"; flags=EEikMenuItemDimmed; },
MENU_ITEM { command=EEikCmdPicoLoadROM; txt="Load new ROM"; },
MENU_ITEM { command=EEikCmdPicoResume; txt="Resume game"; flags=EEikMenuItemDimmed; },
MENU_ITEM { command=EEikCmdPicoReset; txt="Reset game"; flags=EEikMenuItemDimmed; },
MENU_ITEM { command=EEikCmdPicoKeys; txt="Configure keys"; },
MENU_ITEM { command=EEikCmdPicoSettings; txt="Settings"; },
MENU_ITEM { command=EEikCmdHelpAbout; txt="About"; flags=EEikMenuItemSeparatorAfter; },
MENU_ITEM { command=EEikCmdExit; txt="Exit"; }
};
}
RESOURCE MENU_PANE r_app_frameskip_menu
{
items=
{
MENU_ITEM { command=EEikCmdPicoFrameskipAuto; txt="Auto"; flags=EEikMenuItemRadioStart | EEikMenuItemSeparatorAfter; },
MENU_ITEM { command=EEikCmdPicoFrameskip0; txt="0"; flags=EEikMenuItemRadioMiddle; },
MENU_ITEM { command=EEikCmdPicoFrameskip1; txt="1"; flags=EEikMenuItemRadioMiddle; },
MENU_ITEM { command=EEikCmdPicoFrameskip2; txt="2"; flags=EEikMenuItemRadioMiddle; },
MENU_ITEM { command=EEikCmdPicoFrameskip4; txt="4"; flags=EEikMenuItemRadioMiddle; },
MENU_ITEM { command=EEikCmdPicoFrameskip8; txt="8"; flags=EEikMenuItemRadioEnd; }
};
}
RESOURCE MENU_PANE r_app_debug_menu
{
items=
{
MENU_ITEM { command=EEikCmdPicoDebugKillEmu; txt="Kill emu proc"; },
MENU_ITEM { command=EEikCmdPicoDebugInfo; txt="info"; }
};
}
/**************************************
*
* about dialog
*
**************************************/
RESOURCE DIALOG r_dialog_about
{
title = "About";
buttons = r_buttons_continue_credits;
flags = EEikDialogFlagWait;
items =
{
DLG_LINE
{
itemflags = EQikDlgItemUseFullWidth | EQikDlgItemDenselyPacked;
type = EEikCtRichTextEditor;
id = ECtlAboutVersion;
control = RTXTED
{
flags = EEikEdwinResizable | EEikEdwinNoAutoSelection | EEikEdwinReadOnly | EEikEdwinWidthInPixels;
numlines = 4;
};
},
DLG_LINE
{
itemflags = EQikDlgItemUseFullWidth | EQikDlgItemDenselyPacked;
type = EEikCtRichTextEditor;
id = ECtlAboutLinks;
control = RTXTED
{
flags = EEikEdwinResizable | EEikEdwinNoAutoSelection | EEikEdwinReadOnly | EEikEdwinWidthInPixels | 0x00200000;
numlines = 4;
};
}
};
}
RESOURCE DLG_BUTTONS r_buttons_continue_credits
{
buttons =
{
DLG_BUTTON { id = EEikBidYes; button = CMBUT { txt = "Credits"; }; },
DLG_BUTTON { id = EEikBidCancel; button = CMBUT { txt = "Continue"; }; flags=EEikLabeledButtonIsDefault; }
};
}
RESOURCE TBUF r_simple_text_about_links
{
buf=
"<f=Corinna><s=11><u>Email</u>: notasas@gmail.com"\
"<p><f=Corinna><s=11><u>Web</u>:<p>http://notaz.atspace.com"\
"<p><f=Corinna><s=11><u>Dave's Web</u>:<p>http://www.finalburn.com";
}
RESOURCE TBUF r_simple_text_about
{
buf=
"<f=Polo><s=26><a=center><fg=RgbDarkBlue>PicodriveN"\
"<p><f=Polo><s=10><a=center>for UIQ2"\
"<p> <p><f=Corinna><s=12>Version %S, by notaz."\
"<p><s=6> <p><s=10>Port based on PicoDrive 0.030 for Pocket PC by Dave";
}
RESOURCE DIALOG r_dialog_credits
{
title = "Credits and thanks";
buttons = R_EIK_BUTTONS_DONE;
flags = EEikDialogFlagWait;
items =
{
DLG_LINE
{
type = EEikCtGlobalTextEditor;
id = ECtlCredits;
control = GTXTED
{
width = 150; height = 200; numlines = 26; flags = EEikEdwinReadOnly | EEikEdwinNoAutoSelection | EEikEdwinDisplayOnly;
};
}
};
}
RESOURCE ARRAY r_tbuf_credits
{
items=
{
LBUF{txt="This emulator uses code from these people / projects:";},
LBUF{txt="";},
LBUF{txt="Dave";},
LBUF{txt="- Cyclone 68000 core, Pico emulation library";},
LBUF{txt="Homepage: http://www.finalburn.com/";},
LBUF{txt="E-mail: david(atsymbol)finalburn.com";},
LBUF{txt="";},
LBUF{txt="Reesy & FluBBa";},
LBUF{txt="- DrZ80, the Z80 emulator written in ARM assembly.";},
LBUF{txt="Homepage: http://reesy.gp32x.de/";},
LBUF{txt="E-mail: drsms_reesy(atsymbol)yahoo.co.uk";},
LBUF{txt="";},
LBUF{txt="Tatsuyuki Satoh, Jarek Burczynski, MultiArcadeMachineEmulator (MAME) development";},
LBUF{txt="- software implementation of Yamaha FM sound generator and";},
LBUF{txt="Texas Instruments SN76489 / SN76496 programmable tone / noise generator";},
LBUF{txt="Homepage: http://www.mame.net/";},
LBUF{txt="";},
LBUF{txt="Additional thanks:";},
LBUF{txt="- Peter van Sebille for ECompXL and his various open-source Symbian projects to learn from.";},
LBUF{txt="- Steve Fischer for his open-source Motorola projects.";},
LBUF{txt="- Charles MacDonald (http://cgfm2.emuviews.com/) for old but still very useful info about genesis hardware.";},
LBUF{txt="- Stéphane Dallongeville for creating Gens and making it open-source.";},
LBUF{txt="- Steve Snake for all that he has done for Genesis emulation scene.";},
LBUF{txt="- Bart Trzynadlowski for his SSFII and 68000 docs.";},
LBUF{txt="- Haze for his research (http://haze.mameworld.info).";},
LBUF{txt="- The development team behind \"Symbian GCC Improvement Project \" (http://www.inf.u-szeged.hu/symbian-gcc/) for their updated compile tools.";},
LBUF{txt="- Mark and Jean-loup for zlib library.";},
LBUF{txt="- Reesy for also finding some Cyclone bugs.";},
LBUF{txt="- Inder for the icons.";}
};
}
/**************************************
*
* debug dialog
*
**************************************/
RESOURCE DIALOG r_dialog_debug
{
title = "debug";
buttons = R_EIK_BUTTONS_DONE;
flags = EEikDialogFlagWait;
items =
{
DLG_LINE
{
type = EEikCtGlobalTextEditor;
id = ECtlDebugEdit;
control = GTXTED
{
width = 150; height = 200; numlines = 26; flags = EEikEdwinReadOnly | EEikEdwinNoAutoSelection | EEikEdwinDisplayOnly;
};
}
};
}
/**************************************
*
* config dialog
*
**************************************/
RESOURCE DIALOG r_pico_config
{
title = "Settings";
buttons = R_EIK_BUTTONS_CANCEL_OK;
flags = EEikDialogFlagWait;
pages = r_pico_config_pages;
}
RESOURCE ARRAY r_pico_config_pages
{
items = {
PAGE
{
id = ECtlOptPageMain;
text = "Main";
lines = r_pico_config_page_main;
},
PAGE
{
id = ECtlOptPageSound;
text = "Sound";
lines = r_pico_config_page_sound;
},
PAGE
{
id = ECtlOptPageMisc;
text = "Misc";
lines = r_pico_config_page_misc;
}
};
}
RESOURCE ARRAY r_pico_config_page_main
{
items = {
DLG_LINE
{
id = ECtlOptRotationLabel;
type = EEikCtLabel;
prompt = "Screen Rotation";
control = LABEL { horiz_align = EEikLabelAlignHLeft; };
},
DLG_LINE
{
id = ECtlOptRotation;
type = EEikCtHorOptionButList;
control = HOROPBUT
{
array_id = r_pico_config_rotation_buttons;
};
},
DLG_LINE
{
id = ECtlOptScreenModeLabel;
type = EEikCtLabel;
prompt = "Screen Mode";
control = LABEL { horiz_align = EEikLabelAlignHLeft; };
},
DLG_LINE
{
id = ECtlOptScreenMode;
type = EEikCtHorOptionButList;
control = HOROPBUT
{
array_id = r_pico_config_screenmode_buttons;
};
},
DLG_LINE
{
id = ECtlOptUseAltRend;
type = EEikCtCheckBox;
prompt = "Fast renderer (inaccurate)";
},
DLG_LINE
{
id = ECtlOptUseAccTiming;
type = EEikCtCheckBox;
prompt = "Accurate timing (slower)";
},
DLG_LINE
{
id = ECtlOptUseAccSprites;
type = EEikCtCheckBox;
prompt = "Accurate sprites (slower)";
},
DLG_LINE
{
id = ECtlOptShowFPS;
type = EEikCtCheckBox;
prompt = "Show FPS";
}
};
}
RESOURCE ARRAY r_pico_config_page_sound
{
items = {
DLG_LINE
{
id = ECtlOptEnableSound;
type = EEikCtCheckBox;
prompt = "Enable sound";
},
DLG_LINE
{
id = ECtlOptChipSelLabel;
type = EEikCtLabel;
prompt = "Emulate these sound chips:";
control = LABEL { horiz_align = EEikLabelAlignHLeft; };
},
DLG_LINE
{
id = ECtlOptEmulateZ80;
type = EEikCtCheckBox;
prompt = "Z80";
},
DLG_LINE
{
id = ECtlOptEmulateYM2612;
type = EEikCtCheckBox;
prompt = "YM2612";
},
DLG_LINE
{
id = ECtlOptEmulateSN76496;
type = EEikCtCheckBox;
prompt = "SN76496 (PSG)";
},
DLG_LINE
{
id = ECtlOptSndQLabel;
type = EEikCtLabel;
prompt = "Quality (lowest is fastest)";
control = LABEL { horiz_align = EEikLabelAlignHLeft; };
},
DLG_LINE
{
id = ECtlOptSndQuality;
type = EEikCtChoiceList;
prompt = "";
control = CHOICELIST { array_id = r_pico_config_snd_quality; };
itemflags = EEikDlgItemNonFocusing;
}
};
}
RESOURCE ARRAY r_pico_config_page_misc
{
items = {
DLG_LINE
{
id = ECtlOpt6ButtonPad;
type = EEikCtCheckBox;
prompt = "6 button pad";
},
DLG_LINE
{
id = ECtlOptGzipStates;
type = EEikCtCheckBox;
prompt = "gzip save states";
},
DLG_LINE
{
id = ECtlOptUseSRAM;
type = EEikCtCheckBox;
prompt = "Use SRAM saves (.srm)";
},
DLG_LINE
{
id = ECtlOptMotDontUseVol;
type = EEikCtCheckBox;
prompt = "Motorola: don't use volume keys for game controls";
},
DLG_LINE
{
id = ECtlOptRegionLabel;
type = EEikCtLabel;
prompt = "Region: ";
control = LABEL { horiz_align = EEikLabelAlignHLeft; };
},
DLG_LINE
{
id = ECtlOptRegion;
type = EEikCtChoiceList;
prompt = "";
control = CHOICELIST { array_id = r_pico_config_region; };
itemflags = EEikDlgItemNonFocusing;
}
};
}
RESOURCE ARRAY r_pico_config_rotation_buttons
{
items = {
OPBUT { id = ECtlOptRotation0; text = "0º"; },
OPBUT { id = ECtlOptRotation90; text = "90º"; },
OPBUT { id = ECtlOptRotation180; text = "180º"; },
OPBUT { id = ECtlOptRotation270; text = "270º"; }
};
}
RESOURCE ARRAY r_pico_config_screenmode_buttons
{
items = {
OPBUT { id = ECtlOptScreenModeCenter; text = "Center"; },
OPBUT { id = ECtlOptScreenModeFit; text = "Fit"; },
OPBUT { id = ECtlOptScreenModeFit2; text = "Fit2"; }
};
}
RESOURCE ARRAY r_pico_config_snd_quality
{
items = {
LBUF { txt = "8000Hz mono"; },
LBUF { txt = "11025Hz mono"; },
LBUF { txt = "16000Hz mono"; },
LBUF { txt = "22050Hz mono"; },
LBUF { txt = "8000Hz stereo"; },
LBUF { txt = "11025Hz stereo"; },
LBUF { txt = "16000Hz stereo"; },
LBUF { txt = "22050Hz stereo"; }
};
}
RESOURCE ARRAY r_pico_config_region
{
items = {
LBUF { txt = "Auto"; },
LBUF { txt = "Europe"; },
LBUF { txt = "USA"; },
LBUF { txt = "Japan PAL"; },
LBUF { txt = "Japan NTSC"; }
};
}

View file

@ -1,14 +0,0 @@
#include <aiftool.rh>
RESOURCE AIF_DATA
{
app_uid=0x1000C193;
caption_list=
{
CAPTION { code=ELangEnglish; caption="PicodriveN"; }
};
num_icons=2;
embeddability=KAppNotEmbeddable;
newfile=KAppDoesNotSupportNewFile;
}

View file

@ -1,33 +0,0 @@
// needed for client interface
#include "../version.h"
#include "../ClientServer.h"
#include "SimpleClient.h"
// Connect to the server - default number of message slots = 4
TInt RServSession::Connect()
{
TInt r=CreateSession(KServerName,Version(),kDefaultMessageSlots);
return(r);
}
// Return the client side version number.
TVersion RServSession::Version(void) const
{
return(TVersion(KPicoMajorVersionNumber,KPicoMinorVersionNumber,0));
}
TInt RServSession::SendReceive(TInt aFunction, TAny* aPtr) const
{
return RSessionBase::SendReceive(aFunction, aPtr);
}
TInt RServSession::Send(TInt aFunction, TAny* aPtr) const
{
return RSessionBase::Send(aFunction, aPtr);
}

View file

@ -1,23 +0,0 @@
#ifndef __SERVSESSION_H__
#define __SERVSESSION_H__
#include <e32base.h>
//**********************************
// RServSession
//**********************************
class RServSession : public RSessionBase
{
public:
RServSession() {}
TInt Connect();
TVersion Version() const;
TInt SendReceive(TInt aFunction,TAny* aPtr) const;
TInt Send(TInt aFunction,TAny* aPtr) const;
};
#endif

View file

@ -1,101 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void targetname(char *dest, char *src)
{
char *p, *p1;
if(strlen(src) < 5 || src[0] == '\t') return;
// goto string end
for(p=src; *p && *p != ' ' && *p != '\r'; p++);
// goto start
for(p1=p; p1 > src && *p1 != '\\'; p1--); p1++;
if(p-p1 > 0) {
strncpy(dest, p1, p-p1);
dest[p-p1] = 0;
}
}
int main(int argc, char *argv[])
{
FILE *f = 0, *fo = 0;
unsigned char buff[512], buff2[128], outname[512];
buff2[0] = 0;
if(argc != 2) {
printf("usage: %s <makefile>\n\n", argv[0]);
return 1;
}
f = fopen(argv[1], "r");
if(!f) {
printf("%s: couldn't open %s\n", argv[0], argv[1]);
return 2;
}
strcpy(outname, argv[1]);
strcat(outname, ".out");
fo = fopen(outname, "w");
if(!fo) {
fclose(f);
printf("%s: couldn't open %s for writing\n", argv[0], outname);
return 3;
}
while(!feof(f)) {
fgets(buff, 512, f);
if(!strncmp(buff, "\t$(GCCUREL)", 11) && !strchr(buff, '>')) {
fprintf(fo, "\t@echo %s: gcc\n\t@$(GCCUREL)", buff2);
fputs(buff+11, fo);
} else if(!strncmp(buff, "\tperl -S ecopyfile.pl", 21) && !strchr(buff, '>')) {
fprintf(fo, "\t@echo %s: perl -S ecopyfile.pl\n\t@perl", buff2);
fputs(buff+5, fo);
} else if(!strncmp(buff, "\tperl -S epocrc.pl", 18) && !strchr(buff, '>')) {
fprintf(fo, "\t@echo %s: perl -S epocrc.pl\n\t@perl", buff2);
fputs(buff+5, fo);
} else if(!strncmp(buff, "\tperl -S epocaif.pl", 19) && !strchr(buff, '>')) {
fprintf(fo, "\t@echo %s: perl -S epocaif.pl\n\t@perl", buff2);
fputs(buff+5, fo);
} else if(!strncmp(buff, "\tperl -S emkdir.pl", 18) && !strchr(buff, '>')) {
fprintf(fo, "\t@echo %s: perl -S emkdir.pl\n\t@perl", buff2);
fputs(buff+5, fo);
} else if(!strncmp(buff, "\tperl -S makedef.pl", 18) && !strchr(buff, '>')) {
fprintf(fo, "\t@echo %s: perl -S makedef.pl\n\t@perl", buff2);
fputs(buff+5, fo);
} else if(!strncmp(buff, "\tld ", 4) && !strchr(buff, '>')) {
fprintf(fo, "\t@echo %s: ld\n\t@ld ", buff2);
fputs(buff+4, fo);
} else if(!strncmp(buff, "\tar ", 4) && !strchr(buff, '>')) {
fprintf(fo, "\t@echo %s: ar\n\t@ar ", buff2);
fputs(buff+4, fo);
} else if(!strncmp(buff, "\tif exist ", 10) && !strchr(buff, '>')) {
fprintf(fo, "\t@echo %s: if exist (del?)\n\t@if exist ", buff2);
fputs(buff+10, fo);
} else if(!strncmp(buff, "\tdlltool ", 9) && !strchr(buff, '>')) {
fprintf(fo, "\t@echo %s: dlltool\n\t@dlltool ", buff2);
fputs(buff+9, fo);
} else if(!strncmp(buff, "\tpetran ", 8) && !strchr(buff, '>')) {
fprintf(fo, "\t@echo %s: petran\n\t@petran ", buff2);
fputs(buff+8, fo);
} else {
// try to get new targetname
targetname(buff2, buff);
fputs(buff, fo);
}
}
// done!
fclose(f);
fclose(fo);
remove(argv[1]);
rename(outname, argv[1]);
return 0;
}

Binary file not shown.

View file

@ -1 +0,0 @@
@..\..\..\..\qconsole-1.60\qtty-1.60\release\qtty --qc-addr P800 --qc-channel 5 --user qconsole --pass server --cmds "put d:\system\apps\picodriven\PICODRIVEN.APP ..\..\..\..\..\epoc32\release\armi\urel\PICODRIVEN.APP" "put d:\system\apps\picodriven\PICODRIVEN.rsc ..\..\..\..\..\epoc32\data\z\system\apps\PicodriveN\PICODRIVEN.rsc" exit

File diff suppressed because it is too large Load diff

View file

@ -1,21 +0,0 @@
// port specific settings
#ifndef PORT_CONFIG_H
#define PORT_CONFIG_H
// draw2.c
#define START_ROW 1 // which row of tiles to start rendering at?
#define END_ROW 27 // ..end
// pico.c
#define CAN_HANDLE_240_LINES 0
// common debug
#if defined(__DEBUG_PRINT)
void dprintf(char *format, ...);
#else
#define dprintf(x...)
#endif
#endif //PORT_CONFIG_H

View file

@ -1,2 +0,0 @@
.equiv START_ROW, 1
.equiv END_ROW, 27

View file

@ -1 +0,0 @@
@..\..\..\qconsole-1.60\qtty-1.60\release\qtty --qc-addr P800 --qc-channel 5 --user qconsole --pass server

View file

@ -1 +0,0 @@
@..\..\..\qconsole-1.60\qtty-1.60\release\qtty --qc-addr P800 --qc-channel 5 --user qconsole --pass server --cmds "put d:\system\apps\picodriven\PICOSMALL.EXE PICOSMALL.EXE" exit

View file

@ -1 +0,0 @@
@..\..\..\qconsole-1.60\qtty-1.60\release\qtty --qc-addr P800 --qc-channel 5 --user qconsole --pass server --cmds "put d:\system\apps\picodriven\PICODRIVEN.APP launcher\PICODRIVEN.APP" "put d:\system\apps\picodriven\PICODRIVEN.rsc launcher\PICODRIVEN.rsc" exit

View file

@ -1,10 +0,0 @@
// version number
#ifndef __VERSION_H
#define __VERSION_H
#define KPicoMajorVersionNumber 0
#define KPicoMinorVersionNumber 93
#define KPicoBuildNumber 0
#endif /* __VERSION_H */

File diff suppressed because it is too large Load diff

View file

@ -1,9 +0,0 @@
#include <e32base.h>
// let's do it in more c-like way
int vidInit(int displayMode, void *vidmem, int p800, int reinit=0);
void vidFree();
void vidDrawFrame(char *noticeStr, char *fpsStr, int num);
void vidKeyConfigFrame(const TUint whichAction, TInt flipClosed);
void vidDrawFCconfigDone();
void vidDrawNotice(const char *txt); // safe to call anytime, draws text for 1 frame

View file

@ -1,491 +0,0 @@
/*******************************************************************
*
* File: App.cpp
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2002, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#include "App.h"
// #include "picodriven.mbg" // bitmap identifiers
#include "rsc/picodrive.rsg" // resource include
#include <eikenv.h>
#include <qbtselectdlg.h>
//#include <gulutil.h>
//#include <bautils.h>
//#include <eikmenub.h> // CEikMenuBar
#include <apgtask.h> // TApaSystemEvent
#include <eikstart.h>
#include <eikedwin.h>
#include <s32strm.h>
#include <qikappui.h>
#include <qikeditcategoryobserver.h>
#include <qikselectfiledlg.h>
#include <qikcommand.h>
#include "Dialogs.h"
#include "engine/debug.h"
#include "../common/emu.h"
#include "emu.h"
extern "C" char menuErrorMsg[];
////////////////////////////////////////////////////////////////
//
// class CPicolAppView
//
////////////////////////////////////////////////////////////////
// Creates and constructs the view.
CPicolAppView* CPicolAppView::NewLC(CQikAppUi& aAppUi, TPicoConfig& aCurrentConfig)
{
CPicolAppView* self = new (ELeave) CPicolAppView(aAppUi, aCurrentConfig);
CleanupStack::PushL(self);
return self;
}
/**
Constructor for the view.
Passes the application UI reference to the construction of the super class.
KNullViewId should normally be passed as parent view for the applications
default view. The parent view is the logical view that is normally activated
when a go back command is issued. KNullViewId will activate the system
default view.
@param aAppUi Reference to the application UI
*/
CPicolAppView::CPicolAppView(CQikAppUi& aAppUi, TPicoConfig& aCurrentConfig)
: CQikViewBase(aAppUi, KNullViewId), iCurrentConfig(aCurrentConfig)
{
}
void CPicolAppView::ConstructL()
{
BaseConstructL();
}
CPicolAppView::~CPicolAppView()
{
}
/**
Inherited from CQikViewBase and called upon by the UI Framework.
It creates the view from resource.
*/
void CPicolAppView::ViewConstructL()
{
// Loads information about the UI configurations this view supports
// together with definition of each view.
ViewConstructFromResourceL(R_APP_UI_CONFIGURATIONS);
UpdateCommandList();
}
/**
Returns the view Id
@return Returns the Uid of the view
*/
TVwsViewId CPicolAppView::ViewId()const
{
return TVwsViewId(KUidPicolApp, KUidPicolMainView);
}
/**
Handles all commands in the view.
Called by the UI framework when a command has been issued.
The command Ids are defined in the .hrh file.
@param aCommand The command to be executed
@see CQikViewBase::HandleCommandL
*/
void CPicolAppView::HandleCommandL(CQikCommand& aCommand)
{
TInt res;
switch(aCommand.Id())
{
case EEikCmdPicoLoadState:
if(iROMLoaded) {
CEikonEnv::Static()->BusyMsgL(_L("Loading State"));
res = CPicoGameSession::Do(PicoMsgLoadState);
CEikonEnv::Static()->BusyMsgCancel();
// emu doesn't start to run if load fails, so we can display this
if(res) CEikonEnv::Static()->InfoMsg(_L("Load Failed"));
}
break;
case EEikCmdPicoSaveState:
if(iROMLoaded) {
CEikonEnv::Static()->BusyMsgL(_L("Saving State"));
res = CPicoGameSession::Do(PicoMsgSaveState);
CEikonEnv::Static()->BusyMsgCancel();
if(res) CEikonEnv::Static()->InfoMsg(_L("Save Failed"));
}
break;
case EEikCmdPicoLoadROM:
DisplayOpenROMDialogL();
DEBUGPRINT(_L("after DisplayOpenROMDialogL()"));
break;
case EEikCmdPicoResume:
CPicoGameSession::Do(PicoMsgResume);
break;
case EEikCmdPicoReset:
CPicoGameSession::Do(PicoMsgReset);
break;
case EEikCmdPicoSettings:
DisplayConfigDialogL();
break;
case EEikCmdHelpAbout:
DisplayAboutDialogL();
break;
case EEikCmdPicoDebugInfo:
DisplayDebugDialogL();
break;
case EEikCmdPicoKeys:
CPicoGameSession::Do(PicoMsgConfigChange, &iCurrentConfig);
CPicoGameSession::Do(PicoMsgKeys);
break;
case EEikCmdPicoFrameskipAuto:
currentConfig.Frameskip = -1;
emu_write_config(0);
break;
case EEikCmdPicoFrameskip0:
currentConfig.Frameskip = 0;
emu_write_config(0);
break;
case EEikCmdPicoFrameskip1:
currentConfig.Frameskip = 1;
emu_write_config(0);
break;
case EEikCmdPicoFrameskip2:
currentConfig.Frameskip = 2;
emu_write_config(0);
break;
case EEikCmdPicoFrameskip4:
currentConfig.Frameskip = 4;
emu_write_config(0);
break;
case EEikCmdPicoFrameskip8:
currentConfig.Frameskip = 8;
emu_write_config(0);
break;
case EEikCmdExit:
emu_Deinit();
CPicoGameSession::freeResources();
//break; // this is intentional
default:
// Go back and exit command will be passed to the CQikViewBase to handle.
CQikViewBase::HandleCommandL(aCommand);
break;
}
}
void CPicolAppView::DisplayOpenROMDialogL()
{
// Array of mimetypes that the dialog shall filter on, if empty all
// mimetypes will be visible.
CDesCArray* mimeArray = new (ELeave) CDesCArrayFlat(1);
CleanupStack::PushL(mimeArray);
// Array that will be filled with the file paths that are choosen
// from the dialog.
CDesCArray* fileArray = new (ELeave) CDesCArraySeg(3);
CleanupStack::PushL(fileArray);
_LIT16(KDlgTitle, "Select a ROM file");
TPtrC8 text8((TUint8*) rom_fname_loaded);
iCurrentConfig.iLastROMFile.Copy(text8);
if( CQikSelectFileDlg::RunDlgLD( *mimeArray, *fileArray, &KDlgTitle, &iCurrentConfig.iLastROMFile) )
{
CEikonEnv::Static()->BusyMsgL(_L("Loading ROM"));
TPtrC16 file = (*fileArray)[0];
//iCurrentConfig.iLastROMFile.Copy(file);
// push the config first
CPicoGameSession::Do(PicoMsgSetAppView, this);
CPicoGameSession::Do(PicoMsgConfigChange, &iCurrentConfig);
TInt res = CPicoGameSession::Do(PicoMsgLoadROM, &file);
CEikonEnv::Static()->BusyMsgCancel();
iROMLoaded = EFalse;
switch (res)
{
case PicoErrRomOpenFailed: {
TBuf<64> mErrorBuff;
TPtrC8 buff8((TUint8*) menuErrorMsg);
mErrorBuff.Copy(buff8);
CEikonEnv::Static()->InfoWinL(_L("Error"), mErrorBuff);
break;
}
case PicoErrOutOfMem:
CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to allocate memory."));
break;
case PicoErrEmuThread:
CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to create emulation thread. Try to restart this application."));
break;
default:
iROMLoaded = ETrue;
break;
}
// errors which leave ROM loaded
switch (res)
{
case PicoErrOutOfMemSnd:
CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to allocate sound buffer, disabled sound."));
break;
case PicoErrGenSnd:
CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to start soundsystem, disabled sound."));
break;
}
if(res == 6 || res == 7) currentConfig.EmuOpt &= ~EOPT_EN_SOUND;
if(iROMLoaded) {
if(iTitleAdded)
ViewContext()->ChangeTextL(EEikCidTitleBarLabel, CPicoGameSession::iRomInternalName);
else ViewContext()->AddTextL (EEikCidTitleBarLabel, CPicoGameSession::iRomInternalName);
iTitleAdded = ETrue;
UpdateCommandList();
}
}
CleanupStack::PopAndDestroy(2, mimeArray);
}
void CPicolAppView::DisplayConfigDialogL()
{
CPicoConfigDialog* configDialog = new(ELeave)CPicoConfigDialog(currentConfig);
emu_pack_config();
configDialog->ExecuteLD(R_PICO_CONFIG);
emu_unpack_config();
emu_write_config(0);
CPicoGameSession::Do(PicoMsgConfigChange, &currentConfig);
}
void CPicolAppView::DisplayAboutDialogL()
{
TInt iButtonRes;
CAboutDialog* dialog = new (ELeave) CAboutDialog;
dialog->PrepareLC(R_PICO_ABOUT);
iButtonRes = dialog->RunLD();
if(iButtonRes == EEikCmdPicoAboutCreditsCmd) {
CCreditsDialog *creditsDialog = new (ELeave) CCreditsDialog();
creditsDialog->PrepareLC(R_PICO_CREDITS);
creditsDialog->RunLD();
}
}
#ifdef __DEBUG_PRINT
extern "C" char *PDebugMain();
#endif
void CPicolAppView::DisplayDebugDialogL()
{
#ifdef __DEBUG_PRINT
CDebugDialog* dialog = new (ELeave) CDebugDialog(PDebugMain());
dialog->PrepareLC(R_PICO_DEBUG);
dialog->RunLD();
#endif
}
void CPicolAppView::UpdateCommandList()
{
CQikCommandManager& commandManager = CQikCommandManager::Static(*iCoeEnv);
CQikCommand *cmd_fs[10];
Mem::FillZ(cmd_fs, sizeof(CQikCommand*)*10);
CQikCommand* cmd_reset = commandManager.Command(*this, EEikCmdPicoReset);
CQikCommand* cmd_savest = commandManager.Command(*this, EEikCmdPicoSaveState);
CQikCommand* cmd_loadst = commandManager.Command(*this, EEikCmdPicoLoadState);
CQikCommand* cmd_resume = commandManager.Command(*this, EEikCmdPicoResume);
cmd_fs[0] = commandManager.Command(*this, EEikCmdPicoFrameskipAuto);
cmd_fs[1] = commandManager.Command(*this, EEikCmdPicoFrameskip0);
cmd_fs[2] = commandManager.Command(*this, EEikCmdPicoFrameskip1);
cmd_fs[3] = commandManager.Command(*this, EEikCmdPicoFrameskip2);
cmd_fs[5] = commandManager.Command(*this, EEikCmdPicoFrameskip4);
cmd_fs[9] = commandManager.Command(*this, EEikCmdPicoFrameskip8);
TBool dimmed = !CPicoGameSession::iEmuRunning || !iROMLoaded;
cmd_reset ->SetDimmed(dimmed);
cmd_savest->SetDimmed(dimmed);
cmd_loadst->SetDimmed(dimmed);
cmd_resume->SetDimmed(dimmed);
// frameskip
TInt fs_index = currentConfig.Frameskip + 1;
if (fs_index >= 0 && fs_index < 10 && cmd_fs[fs_index])
{
cmd_fs[fs_index]->SetChecked(ETrue);
}
}
////////////////////////////////////////////////////////////////
//
// class CPicolAppUi
//
////////////////////////////////////////////////////////////////
void CPicolAppUi::ConstructL()
{
BaseConstructL();
// Create the view and add it to the framework
iAppView = CPicolAppView::NewLC(*this, ((CPicolDocument *)Document())->iCurrentConfig);
AddViewL(*iAppView);
CleanupStack::Pop(iAppView);
}
////////////////////////////////////////////////////////////////
//
// CPicolDocument
//
////////////////////////////////////////////////////////////////
CPicolDocument::CPicolDocument(CQikApplication& aApp)
: CQikDocument(aApp)
{
}
CQikAppUi* CPicolDocument::CreateAppUiL()
{
return new(ELeave) CPicolAppUi;
}
/**
Called by the framework when ::SaveL has been called.
*/
void CPicolDocument::StoreL(CStreamStore& aStore, CStreamDictionary& aStreamDic) const
{
#if 0
RStoreWriteStream stream;
TStreamId preferenceId = stream.CreateLC(aStore);
aStreamDic.AssignL(KUidPicolStore, preferenceId);
// Externalize preference
stream << iCurrentConfig;
// Ensures that any buffered data is written to aStore
stream.CommitL();
CleanupStack::PopAndDestroy(); // stream
#endif
/*
// tmp
TInt res;
RFile logFile;
res = logFile.Replace(CEikonEnv::Static()->FsSession(), _L("C:\\Shared\\pico.cfg"), EFileWrite|EFileShareAny);
if(!res) {
logFile.Write(TPtr8((TUint8 *)&iCurrentConfig, sizeof(iCurrentConfig), sizeof(iCurrentConfig)));
logFile.Close();
}
*/
}
/**
Called by the framework on application start.
Loads the application data from disk, i.e. domain data and preferences.
*/
void CPicolDocument::RestoreL(const CStreamStore& aStore, const CStreamDictionary& aStreamDic)
{
#if 0
// Find the stream ID of the model data from the stream dictionary:
TStreamId preferenceId(aStreamDic.At(KUidPicolStore));
RStoreReadStream stream;
stream.OpenLC(aStore, preferenceId);
if(preferenceId != KNullStreamId)
{
// Interalize preference and model
stream >> iCurrentConfig;
}
CleanupStack::PopAndDestroy(); // stream
#endif
// tmp
/* TInt res;
RFile logFile;
res = logFile.Open(CEikonEnv::Static()->FsSession(), _L("C:\\Shared\\pico.cfg"), EFileRead|EFileShareAny);
if(!res) {
TPtr8 ptr((TUint8 *)&iCurrentConfig, sizeof(iCurrentConfig), sizeof(iCurrentConfig));
logFile.Read(ptr);
logFile.Close();
}*/
}
////////////////////////////////////////////////////////////////
//
// framework
//
////////////////////////////////////////////////////////////////
CApaDocument* CPicolApplication::CreateDocumentL()
{
return new (ELeave) CPicolDocument(*this);
}
EXPORT_C CApaApplication* NewApplication()
{
return new CPicolApplication;
}
TUid CPicolApplication::AppDllUid() const
{
return KUidPicolApp;
}
extern "C" TInt my_SetExceptionHandler(TInt, TExceptionHandler, TUint32);
GLDEF_C TInt E32Main()
{
// doesn't work :(
User::SetExceptionHandler(ExceptionHandler, (TUint32) -1);
// my_SetExceptionHandler(KCurrentThreadHandle, ExceptionHandler, 0xffffffff);
emu_Init();
return EikStart::RunApplication(NewApplication);
}

View file

@ -1,113 +0,0 @@
/*******************************************************************
*
* File: App.h
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2001, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#ifndef __APP_H
#define __APP_H
#include <coecntrl.h>
#include <coeccntx.h>
#include <coemain.h>
#include <qikappui.h>
#include <qikapplication.h>
#include <qikviewbase.h>
//#include <eikapp.h>
#include <qikdocument.h>
#include "Engine.h"
#include "picodrive.hrh"
const TUid KUidPicolApp = { 0xA00010F3 };
const TUid KUidPicolMainView = { 0x00000001 };
//const TUid KUidPicolFOView = { 0x1000C194 };
//const TUid KUidPicolFCView = { 0x1000C195 };
const TUid KUidPicolStore = { 0x00000011 }; // store stream UID
//enum
//{
// EScreenModeFlipOpen = 0,
// EScreenModeFlipClosed
//};
extern "C" struct _currentConfig_t;
class CPicolAppView : public CQikViewBase
{
public:
static CPicolAppView* NewLC(CQikAppUi& aAppUi, TPicoConfig &aCurrentConfig);
~CPicolAppView();
// from CQikViewBase
TVwsViewId ViewId()const;
void HandleCommandL(CQikCommand& aCommand);
void UpdateCommandList();
protected:
// from CQikViewBase
void ViewConstructL();
private:
CPicolAppView(CQikAppUi& aAppUi, TPicoConfig &aCurrentConfig);
void ConstructL();
protected: // new stuf
void DisplayAboutDialogL();
void DisplayOpenROMDialogL();
void DisplayConfigDialogL();
void DisplayDebugDialogL();
/* void StopGame();
void RunGameL();*/
private:
TPicoConfig &iCurrentConfig;
TBool iROMLoaded;
TBool iTitleAdded;
};
class CPicolAppUi : public CQikAppUi
{
public:
// CPicolAppUi();
void ConstructL();
CPicolAppView* iAppView;
};
class CPicolDocument : public CQikDocument
{
public:
CPicolDocument(CQikApplication& aApp);
void StoreL(CStreamStore& aStore, CStreamDictionary& aStreamDic) const;
void RestoreL(const CStreamStore& aStore, const CStreamDictionary& aStreamDic);
TPicoConfig iCurrentConfig;
private: // from CQikDocument
CQikAppUi* CreateAppUiL();
};
class CPicolApplication : public CQikApplication
{
private: // from CApaApplication
CApaDocument* CreateDocumentL();
TUid AppDllUid() const;
};
#endif

View file

@ -1,477 +0,0 @@
/*******************************************************************
*
* File: CSimpleTextParser.cpp
*
* Author: Peter van Sebille (peter@yipton.net)
*
* (c) Copyright 2002, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#include "CSimpleTextParser.h"
enum
{
EBadTag,
EBadZeroLengthTag,
EBadIntegerParam,
EBadAlignmentParam,
EBadRgbColorParam
};
void Panic(TInt aPanic)
{
User::Panic(_L("STP"), aPanic);
}
CSimpleTextFormatParser* CSimpleTextFormatParser::NewLC()
{
CSimpleTextFormatParser* self = new(ELeave)CSimpleTextFormatParser;
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
CSimpleTextFormatParser::~CSimpleTextFormatParser()
{
delete iParaFormat;
}
void CSimpleTextFormatParser::ConstructL()
{
iParaFormat = CParaFormat::NewL();
}
void CSimpleTextFormatParser::SetBold(TBool aEnable)
{
iCharFormat.iFontSpec.iFontStyle.SetStrokeWeight(aEnable ? EStrokeWeightBold : EStrokeWeightNormal);
iCharMask.ClearAll();
iCharMask.SetAttrib(EAttFontStrokeWeight);
iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
}
void CSimpleTextFormatParser::SetItalic(TBool aEnable)
{
iCharFormat.iFontSpec.iFontStyle.SetPosture(aEnable ? EPostureItalic : EPostureUpright);
iCharMask.ClearAll();
iCharMask.SetAttrib(EAttFontPosture);
iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
}
void CSimpleTextFormatParser::SetUnderLine(TBool aEnable)
{
iCharFormat.iFontPresentation.iUnderline = aEnable ? EUnderlineOn : EUnderlineOff;
iCharMask.ClearAll();
iCharMask.SetAttrib(EAttFontUnderline);
iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
}
void CSimpleTextFormatParser::SetHiddenText(TBool aEnable)
{
iCharFormat.iFontPresentation.iHiddenText = aEnable;
iCharMask.ClearAll();
iCharMask.SetAttrib(EAttFontHiddenText);
iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
}
TRgb CSimpleTextFormatParser::ForegroundColor()
{
iCharMask.ClearAll();
iCharMask.SetAttrib(EAttColor);
iRichText->GetCharFormat(iCharFormat, iCharMask, TextPos(), 0);
return iCharFormat.iFontPresentation.iTextColor;
}
void CSimpleTextFormatParser::SetForegroundColor(const TRgb& aColor)
{
iCharFormat.iFontPresentation.iTextColor = aColor;
iCharMask.ClearAll();
iCharMask.SetAttrib(EAttColor);
iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
}
void CSimpleTextFormatParser::SetBackgroundColor(const TRgb& aColor)
{
iParaFormat->iFillColor = aColor;
iParaMask.ClearAll();
iParaMask.SetAttrib(EAttFillColor);
iRichText->ApplyParaFormatL(iParaFormat, iParaMask, ParaPos(), 0);
}
void CSimpleTextFormatParser::NewParagraph()
{
iCurrentPara++;
iRichText->AppendParagraphL();
AppendTextL(_L(""));
}
void CSimpleTextFormatParser::SetAlignment(CParaFormat::TAlignment aAlignment)
{
iParaFormat->iHorizontalAlignment = aAlignment;
iParaMask.ClearAll();
iParaMask.SetAttrib(EAttAlignment);
iRichText->ApplyParaFormatL(iParaFormat, iParaMask, ParaPos(), 0);
}
void CSimpleTextFormatParser::SetFontHeight(TInt aHeight)
{
iCharFormat.iFontSpec.iHeight = (aHeight * KTwipsPerInch)/KPointsPerInch;
iCharMask.ClearAll();
iCharMask.SetAttrib(EAttFontHeight);
iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
}
void CSimpleTextFormatParser::SetFontName(const TDesC& aName)
{
iCharFormat.iFontSpec.iTypeface.iName = aName;
iCharFormat.iFontSpec.iTypeface.SetAttributes(0);
iCharFormat.iFontSpec.iTypeface.SetIsProportional(ETrue);
iCharMask.ClearAll();
iCharMask.SetAttrib(EAttFontTypeface);
iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
}
/*
* Character formatting:
* <b> Bold on
* </b> Bold of
* <i> Italic on
* </i> Italic off
* <u> Underline on
* </u> Underline off
* <h> Hidden text on **doesn't work**
* </h> Hidden text off **doesn't work**
* <f=name> Fontname: name (type: string)
* <s=size> Fontsize: size (type: integer)
* <fg=color> Foreground color: color (type: color)
* </fg> Restore foreground color
*
* Paragraph formatting:
* <p> New paragraph - will reset both character & paragraph formatting to defaults
* <a=align> Alignment: aling (type: alignement)
* <bg=color> Background color: color (type: color) **doesn't work**
*
* Special characters:
* </<> The character: <
*
* Types:
* - string:
* - integer: Either decimal or hexidecimal value
* - color: Either integer specifing rgb value, or (r,g,b) in which r, g and b are of type integer
* - align: element of enumeration {center, left, right}
*
* Comments:
* The syntax/parser is fairly simplistic. The parser is not trying to match a tag like
* <tag> </tag> as XML/HTML do. Basically, when it encounters a tag (e.g., <b>) it will
* simply instruct the the editor to apply the formatting from the current position as
* specified by the tag (e.g., enable bold). For example, <b><b>Hello</b>World</b> results
* in Hello displayed in a Bold font and World in a normal font.
*
* The only case where state is maintained is when using <fg=color> and </fg>. The current
* fg color is stored when parsing <fg=color> and restored when doing </fg>. Again, <fg> and
* </fg> don't have the XML/HTML <tag> </tag> behavior. For example:
* <fg=red>Peter<fg=blue>was</fg></fg>here
* results in "Peter" displayed in red, "was" displayed in blue and "here" displayed in red.
* It literally goes like this:
* 1) <fg=red> --> apply editor text color red, previous color = whatever the editor's text color is now
* 2) <fg=blue> --> apply editor text color blue, previous color = whatever the editor's text color
* is now --> red
* 3) </fg> --> apply editor text to previous color --> red
* 4) </fg> --> apply editor text to previous color --> red
*
* What you probably wanted was:
* <fg=red>Peter</fg><fg=blue>was</fg>here
* Now "Peter" is displayed in red, "was" in blue and "here" in the default editor's color
*/
static TUint32 ParseInteger(const TDesC& aString)
{
TUint32 val = 0;
TBool parsed = EFalse;
if (aString.Length() > 2)
{
if ((aString[0] == '0') && ((aString[0] == 'x') || (aString[0] == 'X')))
{
TLex lex(aString.Right(aString.Length()-2));
if (lex.Val(val, EHex) != KErrNone)
{
__ASSERT_DEBUG(ETrue, Panic(EBadIntegerParam));
}
parsed = ETrue;
}
}
if (!parsed)
{
TLex lex(aString);
if (lex.Val(val, EDecimal) != KErrNone)
{
__ASSERT_DEBUG(ETrue, Panic(EBadIntegerParam));
}
}
return val;
}
static TRgb ParseColor(const TDesC& aString)
{
if (aString.Length() > 0)
{
if (aString[0] == 'R')
{
if (aString.Compare(_L("RgbBlack")) == 0)
return KRgbBlack;
else if (aString.Compare(_L("RgbDarkGray")) == 0)
return KRgbDarkGray;
else if (aString.Compare(_L("RgbDarkRed")) == 0)
return KRgbDarkRed;
else if (aString.Compare(_L("RgbDarkGreen")) == 0)
return KRgbDarkGreen;
else if (aString.Compare(_L("RgbDarkYellow")) == 0)
return KRgbDarkYellow;
else if (aString.Compare(_L("RgbDarkBlue")) == 0)
return KRgbDarkBlue;
else if (aString.Compare(_L("RgbDarkMagenta")) == 0)
return KRgbDarkMagenta;
else if (aString.Compare(_L("RgbDarkCyan")) == 0)
return KRgbDarkCyan;
else if (aString.Compare(_L("RgbRed")) == 0)
return KRgbRed;
else if (aString.Compare(_L("RgbGreen")) == 0)
return KRgbGreen;
else if (aString.Compare(_L("RgbYellow")) == 0)
return KRgbYellow;
else if (aString.Compare(_L("RgbBlue")) == 0)
return KRgbBlue;
else if (aString.Compare(_L("RgbMagenta")) == 0)
return KRgbMagenta;
else if (aString.Compare(_L("RgbCyan")) == 0)
return KRgbCyan;
else if (aString.Compare(_L("RgbGray")) == 0)
return KRgbGray;
else if (aString.Compare(_L("RgbWhite")) == 0)
return KRgbWhite;
else
{
__ASSERT_DEBUG(ETrue, Panic(EBadRgbColorParam));
}
}
return ParseInteger(aString);
}
__ASSERT_DEBUG(ETrue, Panic(EBadRgbColorParam));
return KRgbBlack;
}
static CParaFormat::TAlignment ParseAlignment(const TDesC& aString)
{
if (aString.Compare(_L("center")) == 0)
{
return CParaFormat::ECenterAlign;
}
else if (aString.Compare(_L("left")) == 0)
{
return CParaFormat::ELeftAlign;
}
else if (aString.Compare(_L("right")) == 0)
{
return CParaFormat::ERightAlign;
}
__ASSERT_DEBUG(ETrue, Panic(EBadAlignmentParam));
return CParaFormat::ECenterAlign;
}
void CSimpleTextFormatParser::ParseTagL(const TDesC& aTag)
{
TInt tagLength = aTag.Length();
if (tagLength == 0)
{
__ASSERT_DEBUG(ETrue, Panic(EBadZeroLengthTag));
return;
}
TPtrC param(_L(""));
TInt pos = aTag.Find(_L("="));
if (pos>0)
{
param.Set(aTag.Right(aTag.Length()-pos-1));
tagLength = pos;
}
TPtrC tag = aTag.Left(tagLength);
// RDebug::Print(_L("tag=%S, param=%S"), &tag, &param);
switch (tagLength)
{
case 1:
{
if (tag.Compare(_L("a")) == 0)
SetAlignment(ParseAlignment(param));
else if (tag.Compare(_L("b")) == 0)
SetBold();
else if (tag.Compare(_L("f")) == 0)
SetFontName(param);
else if (tag.Compare(_L("h")) == 0)
SetHiddenText();
else if (tag.Compare(_L("i")) == 0)
SetItalic();
else if (tag.Compare(_L("p")) == 0)
NewParagraph();
else if (tag.Compare(_L("s")) == 0)
SetFontHeight(ParseInteger(param));
else if (tag.Compare(_L("u")) == 0)
SetUnderLine();
else
{
__ASSERT_DEBUG(ETrue, Panic(EBadTag));
}
break;
}
case 2:
{
if (tag.Compare(_L("/b")) == 0)
SetBold(EFalse);
if (tag.Compare(_L("bg")) == 0)
SetBackgroundColor(ParseColor(param));
if (tag.Compare(_L("fg")) == 0)
{
iPrevFgColor = ForegroundColor();
SetForegroundColor(ParseColor(param));
}
else if (tag.Compare(_L("/h")) == 0)
SetHiddenText(EFalse);
else if (tag.Compare(_L("/i")) == 0)
SetItalic(EFalse);
else if (tag.Compare(_L("/u")) == 0)
SetUnderLine(EFalse);
else if (tag.Compare(_L("/<")) == 0)
AppendTextL(_L("<"));
break;
}
case 3:
{
if (tag.Compare(_L("/fg")) == 0)
SetForegroundColor(iPrevFgColor);
break;
}
default:
;
}
}
void CSimpleTextFormatParser::ParseL(const TDesC& aSimpleText, CRichText& aRichText)
{
iRichText = &aRichText;
iCurrentPara = 0;
TBool done = EFalse;
TPtrC simpleText(aSimpleText);
do
{
TInt pos = simpleText.Locate('<');
if (pos > 0)
{
AppendTextL(simpleText.Left(pos));
simpleText.Set(simpleText.Right(simpleText.Length() - pos));
}
else if (pos == 0)
{
pos = simpleText.Locate('>');
if (pos<=0)
User::Leave(KErrArgument);
ParseTagL(simpleText.Mid(1, pos-1));
simpleText.Set(simpleText.Right(simpleText.Length() - pos - 1));
}
else
{
AppendTextL(simpleText);
done = ETrue;
}
} while (!done);
}
TInt CSimpleTextFormatParser::TextPos()
{
return iRichText->DocumentLength();
#if 0
TInt pos, length;
pos = iRichText->CharPosOfParagraph(length, iCurrentPara);
return pos+length-1;
#endif
}
TInt CSimpleTextFormatParser::ParaPos()
{
return TextPos();
#if 0
TInt pos, length;
pos = iRichText->CharPosOfParagraph(length, iCurrentPara);
return pos+length-1;
#endif
}
void CSimpleTextFormatParser::AppendTextL(const TDesC& aText)
{
// RDebug::Print(_L("text=%S"), &aText);
iRichText->InsertL(TextPos(), aText);
}
#if 0
void CTestDialog::ShowTextL(CRichText& aRichText)
{
aRichText.Reset();
TCharFormat charFormat;
TCharFormatMask charMask;
aRichText.GetCharFormat(charFormat, charMask, 0, 0);
TInt para = 0;
AppendTextL(_L("http://www.yipton.net"), aRichText);
para++;
aRichText.AppendParagraphL();
CParaFormat* paraFormat = CParaFormat::NewLC();
TParaFormatMask paraMask;
aRichText.GetParaFormatL(paraFormat, paraMask, ParaPos(aRichText, para), 0);
paraFormat->iHorizontalAlignment = CParaFormat::ECenterAlign;
paraMask.ClearAll();
paraMask.SetAttrib(EAttAlignment);
aRichText.ApplyParaFormatL(paraFormat, paraMask, ParaPos(aRichText, para), 0);
charFormat.iFontPresentation.iUnderline = EUnderlineOn;
charFormat.iFontSpec.iFontStyle.SetPosture(EPostureItalic);
charMask.ClearAll();
charMask.SetAttrib(EAttFontPosture);
charMask.SetAttrib(EAttFontUnderline);
aRichText.ApplyCharFormatL(charFormat, charMask, TextPos(aRichText, para));
AppendTextL(_L("mailto:Peter is here"), aRichText, para);
para++;
aRichText.AppendParagraphL();
TFontSpec fontSpec(_L("edmunds"), 20 * KPointsPerInch);
// CFont* font = NULL;
// iCoeEnv->ScreenDevice()->GetNearestFontInTwips(font, fontSpec);
charFormat.iFontSpec = fontSpec;
charMask.ClearAll();
charMask.SetAttrib(EAttFontHeight);
charMask.SetAttrib(EAttFontTypeface);
aRichText.ApplyCharFormatL(charFormat, charMask, TextPos(aRichText, para));
AppendTextL(_L("mailto:Peter is here"), aRichText, para);
CleanupStack::PopAndDestroy();
}
#endif

View file

@ -1,59 +0,0 @@
/*******************************************************************
*
* File: CSimpleTextParser.h
*
* Author: Peter van Sebille (peter@yipton.net)
*
* (c) Copyright 2002, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#ifndef __CSIMPLE_TEXT_PARSER_H
#define __CSIMPLE_TEXT_PARSER_H
#include <e32def.h>
#include <txtrich.h> // CRichText
#include <eikrted.h> // CEikRichTextEditor
class CSimpleTextFormatParser : public CBase
{
public:
static CSimpleTextFormatParser* NewLC();
void ParseL(const TDesC& aPSTText, CRichText& aRichText);
protected:
CSimpleTextFormatParser(){}
~CSimpleTextFormatParser();
void ConstructL();
void ParseTagL(const TDesC& aTag);
TRgb ForegroundColor();
void SetBold(TBool aEnable=ETrue);
void SetItalic(TBool aEnable=ETrue);
void SetUnderLine(TBool aEnable=ETrue);
void SetFontHeight(TInt aHeight);
void SetFontName(const TDesC& aName);
void SetHiddenText(TBool aEnable=ETrue);
void SetForegroundColor(const TRgb& aColor);
void NewParagraph();
void SetAlignment(CParaFormat::TAlignment aAlignment);
void SetBackgroundColor(const TRgb& aColor);
void AppendTextL(const TDesC& aText);
TInt TextPos();
TInt ParaPos();
CRichText* iRichText;
TCharFormat iCharFormat;
TCharFormatMask iCharMask;
CParaFormat* iParaFormat;
TParaFormatMask iParaMask;
TInt iCurrentPara;
TRgb iPrevFgColor;
};
#endif /* __CSIMPLE_TEXT_PARSER_H */

View file

@ -1,361 +0,0 @@
/*******************************************************************
*
* File: Dialogs.cpp
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2002, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#include "Dialogs.h"
#include "Engine.h"
#include "picodrive.hrh"
#include "rsc/picodrive.rsg"
#include "version.h"
#include "CSimpleTextParser.h"
#include <txtrich.h> // CRichText
#include <eikrted.h> // CEikRichTextEditor
#include <qikvertoptionbuttonlist.h> // CEikHorOptionButtonList
#include <eikopbut.h> // CEikOptionButton
#include <eikedwin.h> // CEikEdwin
#include <quartzkeys.h> // EQuartzKeyTwoWayDown
#include <qikcommand.h>
#include "../common/emu.h"
/************************************************
*
* config Dialog
*
************************************************/
CPicoConfigDialog::CPicoConfigDialog(_currentConfig_t &cfg) : config(cfg)
{
}
void CPicoConfigDialog::PostLayoutDynInitL()
{
CEikHorOptionButtonList *buttons_rot = (CEikHorOptionButtonList*) Control( ECtlOptRotation );
CEikHorOptionButtonList *buttons_disp = (CEikHorOptionButtonList*) Control( ECtlOptScreenMode );
CEikCheckBox *chkbox_altrend= (CEikCheckBox*) Control( ECtlOptUseAltRend );
// CEikCheckBox *chkbox_acctmng= (CEikCheckBox*) Control( ECtlOptUseAccTiming );
CEikCheckBox *chkbox_sram = (CEikCheckBox*) Control( ECtlOptUseSRAM );
CEikCheckBox *chkbox_fps = (CEikCheckBox*) Control( ECtlOptShowFPS );
CEikCheckBox *chkbox_sound = (CEikCheckBox*) Control( ECtlOptEnableSound );
CEikCheckBox *chkbox_z80 = (CEikCheckBox*) Control( ECtlOptEmulateZ80 );
CEikCheckBox *chkbox_ym2612 = (CEikCheckBox*) Control( ECtlOptEmulateYM2612 );
CEikCheckBox *chkbox_sn76496= (CEikCheckBox*) Control( ECtlOptEmulateSN76496 );
CEikChoiceListBase *combo_sndq = (CEikChoiceListBase*) Control( ECtlOptSndQuality );
CEikCheckBox *chkbox_6bpad = (CEikCheckBox*) Control( ECtlOpt6ButtonPad );
CEikCheckBox *chkbox_gzipst = (CEikCheckBox*) Control( ECtlOptGzipStates );
// CEikCheckBox *chkbox_accsprt= (CEikCheckBox*) Control( ECtlOptUseAccSprites );
CEikChoiceListBase *combo_region = (CEikChoiceListBase*) Control( ECtlOptRegion );
CEikOptionButton *opt_fit2 = (CEikOptionButton*) buttons_disp->ComponentControl( TPicoConfig::PMFit2 );
CEikCheckBox *chkbox_cdda = (CEikCheckBox*) Control( ECtlOptCDcdda );
CEikCheckBox *chkbox_pcm = (CEikCheckBox*) Control( ECtlOptCDpcm );
CEikCheckBox *chkbox_ramcart= (CEikCheckBox*) Control( ECtlOptCDramcart );
CEikCheckBox *chkbox_sclrot = (CEikCheckBox*) Control( ECtlOptCDscalerot );
CEikCheckBox *chkbox_bsync = (CEikCheckBox*) Control( ECtlOptCDbettersync );
buttons_rot ->SetButtonById(ECtlOptRotation0 + config.rotation);
buttons_disp->SetButtonById(ECtlOptScreenModeCenter + config.scaling);
chkbox_sram ->SetState(config.EmuOpt & 1 ? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_fps ->SetState(config.EmuOpt & 2 ? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_sound ->SetState(config.EmuOpt & 4 ? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_gzipst ->SetState(config.EmuOpt & 8 ? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_z80 ->SetState(config.s_PicoOpt& 4 ? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_ym2612 ->SetState(config.s_PicoOpt& 1 ? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_sn76496->SetState(config.s_PicoOpt& 2 ? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_altrend->SetState(config.s_PicoOpt& 0x10? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_6bpad ->SetState(config.s_PicoOpt& 0x20? CEikButtonBase::ESet : CEikButtonBase::EClear);
// chkbox_acctmng->SetState(config.s_PicoOpt& 0x40? CEikButtonBase::ESet : CEikButtonBase::EClear);
// chkbox_accsprt->SetState(config.s_PicoOpt& 0x80? CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_cdda ->SetState(config.s_PicoOpt&0x0800?CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_pcm ->SetState(config.s_PicoOpt&0x0400?CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_ramcart->SetState(config.s_PicoOpt&0x8000?CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_sclrot ->SetState(config.s_PicoOpt&0x1000?CEikButtonBase::ESet : CEikButtonBase::EClear);
chkbox_bsync ->SetState(config.s_PicoOpt&0x2000?CEikButtonBase::ESet : CEikButtonBase::EClear);
// dim "fit2" if we are not in 0 or 180 mode
if (config.rotation != TPicoConfig::PRot0 && config.rotation != TPicoConfig::PRot180)
opt_fit2->SetDimmed(ETrue);
// dim some stuff for alternative renderer
if (config.s_PicoOpt & 0x10) {
// dim accurate sprites
//chkbox_accsprt->SetState(CEikButtonBase::EClear);
//chkbox_accsprt->SetDimmed(ETrue);
// dim fit
if(buttons_rot->LabeledButtonId() == ECtlOptRotation0 || buttons_rot->LabeledButtonId() == ECtlOptRotation180)
((CEikOptionButton*)(buttons_disp->ComponentControl(TPicoConfig::PMFit)))->SetDimmed(ETrue);
}
TInt sel = 0;
switch (config.s_PsndRate) {
case 11025: sel = 1; break;
case 16000: sel = 2; break;
case 22050: sel = 3; break;
case 44100: sel = 4; break;
}
sel += (config.s_PicoOpt&8) ? 5 : 0;
if (sel >= 10) sel = 0;
combo_sndq->SetCurrentItem(sel);
switch(config.s_PicoRegion) {
case 1: sel = 4; break;
case 2: sel = 3; break;
case 4: sel = 2; break;
case 8: sel = 1; break;
default:sel = 0; // auto
}
combo_region->SetCurrentItem(sel);
}
TBool CPicoConfigDialog::OkToExitL(TInt aButtonId)
{
if(aButtonId != EEikBidOk) return ETrue;
CEikHorOptionButtonList *buttons_rot = (CEikHorOptionButtonList*) Control( ECtlOptRotation );
CEikHorOptionButtonList *buttons_disp = (CEikHorOptionButtonList*) Control( ECtlOptScreenMode );
CEikCheckBox *chkbox_altrend= (CEikCheckBox*) Control( ECtlOptUseAltRend );
// CEikCheckBox *chkbox_acctmng= (CEikCheckBox*) Control( ECtlOptUseAccTiming );
CEikCheckBox *chkbox_sram = (CEikCheckBox*) Control( ECtlOptUseSRAM );
CEikCheckBox *chkbox_fps = (CEikCheckBox*) Control( ECtlOptShowFPS );
CEikCheckBox *chkbox_sound = (CEikCheckBox*) Control( ECtlOptEnableSound );
CEikCheckBox *chkbox_z80 = (CEikCheckBox*) Control( ECtlOptEmulateZ80 );
CEikCheckBox *chkbox_ym2612 = (CEikCheckBox*) Control( ECtlOptEmulateYM2612 );
CEikCheckBox *chkbox_sn76496= (CEikCheckBox*) Control( ECtlOptEmulateSN76496 );
CEikChoiceListBase *combo_sndq = (CEikChoiceListBase*) Control( ECtlOptSndQuality );
CEikCheckBox *chkbox_6bpad = (CEikCheckBox*) Control( ECtlOpt6ButtonPad );
CEikCheckBox *chkbox_gzipst = (CEikCheckBox*) Control( ECtlOptGzipStates );
// CEikCheckBox *chkbox_accsprt= (CEikCheckBox*) Control( ECtlOptUseAccSprites );
CEikChoiceListBase *combo_region = (CEikChoiceListBase*) Control( ECtlOptRegion );
CEikCheckBox *chkbox_cdda = (CEikCheckBox*) Control( ECtlOptCDcdda );
CEikCheckBox *chkbox_pcm = (CEikCheckBox*) Control( ECtlOptCDpcm );
CEikCheckBox *chkbox_ramcart= (CEikCheckBox*) Control( ECtlOptCDramcart );
CEikCheckBox *chkbox_sclrot = (CEikCheckBox*) Control( ECtlOptCDscalerot );
CEikCheckBox *chkbox_bsync = (CEikCheckBox*) Control( ECtlOptCDbettersync );
config.rotation = (TPicoConfig::TPicoScreenRotation) (buttons_rot->LabeledButtonId() - ECtlOptRotation0);
config.scaling = (TPicoConfig::TPicoScreenMode) (buttons_disp->LabeledButtonId() - ECtlOptScreenModeCenter);
if(chkbox_sram ->State() == CEikButtonBase::ESet) config.EmuOpt |= 1; else config.EmuOpt &= ~1;
if(chkbox_fps ->State() == CEikButtonBase::ESet) config.EmuOpt |= 2; else config.EmuOpt &= ~2;
if(chkbox_sound ->State() == CEikButtonBase::ESet) config.EmuOpt |= 4; else config.EmuOpt &= ~4;
if(chkbox_gzipst ->State() == CEikButtonBase::ESet) config.EmuOpt |= 8; else config.EmuOpt &= ~8;
if(chkbox_z80 ->State() == CEikButtonBase::ESet) config.s_PicoOpt|= 4; else config.s_PicoOpt&= ~4;
if(chkbox_ym2612 ->State() == CEikButtonBase::ESet) config.s_PicoOpt|= 1; else config.s_PicoOpt&= ~1;
if(chkbox_sn76496->State() == CEikButtonBase::ESet) config.s_PicoOpt|= 2; else config.s_PicoOpt&= ~2;
if(chkbox_altrend->State() == CEikButtonBase::ESet) config.s_PicoOpt|= 0x10;else config.s_PicoOpt&= ~0x10;
if(chkbox_6bpad ->State() == CEikButtonBase::ESet) config.s_PicoOpt|= 0x20;else config.s_PicoOpt&= ~0x20;
// if(chkbox_acctmng->State() == CEikButtonBase::ESet) config.s_PicoOpt|= 0x40;else config.s_PicoOpt&= ~0x40;
// if(chkbox_accsprt->State() == CEikButtonBase::ESet) config.s_PicoOpt|= 0x80;else config.s_PicoOpt&= ~0x80;
if(chkbox_cdda ->State() == CEikButtonBase::ESet) config.s_PicoOpt |= 0x0800; else config.s_PicoOpt&= ~0x0800;
if(chkbox_pcm ->State() == CEikButtonBase::ESet) config.s_PicoOpt |= 0x0400; else config.s_PicoOpt&= ~0x0400;
if(chkbox_ramcart->State() == CEikButtonBase::ESet) config.s_PicoOpt |= 0x8000; else config.s_PicoOpt&= ~0x8000;
if(chkbox_sclrot ->State() == CEikButtonBase::ESet) config.s_PicoOpt |= 0x1000; else config.s_PicoOpt&= ~0x1000;
if(chkbox_bsync ->State() == CEikButtonBase::ESet) config.s_PicoOpt |= 0x2000; else config.s_PicoOpt&= ~0x2000;
TInt sel = combo_sndq->CurrentItem();
if(sel >= 5) { config.s_PicoOpt |= 8; sel-=5; } else config.s_PicoOpt &= ~8;
switch (sel) {
default:config.s_PsndRate = 8000; break;
case 1: config.s_PsndRate = 11025; break;
case 2: config.s_PsndRate = 16000; break;
case 3: config.s_PsndRate = 22050; break;
case 4: config.s_PsndRate = 44100; break;
}
switch (combo_region->CurrentItem()) {
case 4: config.s_PicoRegion = 1; break;
case 3: config.s_PicoRegion = 2; break;
case 2: config.s_PicoRegion = 4; break;
case 1: config.s_PicoRegion = 8; break;
default:config.s_PicoRegion = 0; // auto
}
return ETrue;
}
// simple GUI stuff needs lots of code
void CPicoConfigDialog::HandleControlStateChangeL(TInt aControlId)
{
if (aControlId == ECtlOptEnableSound)
{
CEikCheckBox *chkbox_sound = (CEikCheckBox*) Control( ECtlOptEnableSound );
CEikCheckBox *chkbox_z80 = (CEikCheckBox*) Control( ECtlOptEmulateZ80 );
CEikCheckBox *chkbox_ym2612 = (CEikCheckBox*) Control( ECtlOptEmulateYM2612 );
CEikCheckBox *chkbox_sn76496= (CEikCheckBox*) Control( ECtlOptEmulateSN76496 );
if(chkbox_sound->State() == CEikButtonBase::ESet) {
// check all sound chips too, but only if they all are not set
if((chkbox_z80->State() | chkbox_ym2612->State() | chkbox_sn76496->State()) == CEikButtonBase::EClear) { // (==0)
chkbox_z80 ->SetState(CEikButtonBase::ESet);
chkbox_ym2612 ->SetState(CEikButtonBase::ESet);
chkbox_sn76496->SetState(CEikButtonBase::ESet);
chkbox_z80 ->DrawDeferred();
chkbox_ym2612 ->DrawDeferred();
chkbox_sn76496->DrawDeferred();
}
} else {
// clear everything, but only if everything is set
if((chkbox_z80->State() & chkbox_ym2612->State() & chkbox_sn76496->State()) == CEikButtonBase::ESet) { // (==1)
chkbox_z80 ->SetState(CEikButtonBase::EClear);
chkbox_ym2612 ->SetState(CEikButtonBase::EClear);
chkbox_sn76496->SetState(CEikButtonBase::EClear);
chkbox_z80 ->DrawDeferred();
chkbox_ym2612 ->DrawDeferred();
chkbox_sn76496->DrawDeferred();
}
}
}
else if(aControlId == ECtlOptUseAltRend || aControlId == ECtlOptRotation)
{
CEikCheckBox *chkbox_altrend= (CEikCheckBox*) Control( ECtlOptUseAltRend );
// CEikCheckBox *chkbox_accsprt= (CEikCheckBox*) Control( ECtlOptUseAccSprites );
CEikHorOptionButtonList *buttons_rot = (CEikHorOptionButtonList*) Control( ECtlOptRotation );
CEikHorOptionButtonList *buttons_disp = (CEikHorOptionButtonList*) Control( ECtlOptScreenMode );
CEikOptionButton *opt_fit = (CEikOptionButton*) buttons_disp->ComponentControl( TPicoConfig::PMFit );
CEikOptionButton *opt_fit2 = (CEikOptionButton*) buttons_disp->ComponentControl( TPicoConfig::PMFit2 );
TBool dimmed = chkbox_altrend->State() == CEikButtonBase::ESet;
// show/hide more stuff for alternative renderer
// chkbox_accsprt->SetDimmed(dimmed);
if(buttons_rot->LabeledButtonId() == ECtlOptRotation0 || buttons_rot->LabeledButtonId() == ECtlOptRotation180) {
opt_fit->SetDimmed(dimmed);
if(dimmed && buttons_disp->LabeledButtonId() == ECtlOptScreenModeFit)
buttons_disp->SetButtonById(ECtlOptScreenModeFit2);
}
else opt_fit->SetDimmed(EFalse);
// chkbox_accsprt->DrawDeferred();
buttons_disp->DrawDeferred();
if(buttons_rot->LabeledButtonId() == ECtlOptRotation0 || buttons_rot->LabeledButtonId() == ECtlOptRotation180) {
opt_fit2->SetDimmed(EFalse);
} else {
if(opt_fit2->State() == CEikButtonBase::ESet) {
buttons_disp->SetButtonById(ECtlOptScreenModeFit);
buttons_disp->DrawDeferred();
}
opt_fit2->SetDimmed(ETrue);
}
opt_fit2->DrawDeferred();
}
}
/************************************************
*
* About Dialog
*
************************************************/
void CAboutDialog::PostLayoutDynInitL()
{
TBuf<16> versionText;
TBuf<512> text;
#if (KPicoBuildNumber != 0)
versionText.Format(_L("%d.%d%d"), KPicoMajorVersionNumber, KPicoMinorVersionNumber, KPicoBuildNumber);
#else
versionText.Format(_L("%d.%d"), KPicoMajorVersionNumber, KPicoMinorVersionNumber);
#endif
CEikRichTextEditor* richTextEd = LocateControlByUniqueHandle<CEikRichTextEditor>(ECtlPicoAboutText);
User::LeaveIfNull(richTextEd);
HBufC *aboutFormat = CEikonEnv::Static()->AllocReadResourceLC(R_PICO_TEXT_ABOUT);
CSimpleTextFormatParser *parser = CSimpleTextFormatParser::NewLC();
text.Format(*aboutFormat, &versionText);
parser->ParseL(text, *richTextEd->RichText());
richTextEd->UpdateAllFieldsL(); // Updates all the fields in the document
CleanupStack::PopAndDestroy(parser);
CleanupStack::PopAndDestroy(aboutFormat);
}
/*************************************************************
*
* Credits dialog
*
**************************************************************/
void CCreditsDialog::PreLayoutDynInitL()
{
CEikEdwin *edwin = LocateControlByUniqueHandle<CEikEdwin>(ECtlPicoCreditsText);
User::LeaveIfNull(edwin);
CDesCArrayFlat* desArray = CEikonEnv::Static()->ReadDesCArrayResourceL(R_PICO_TBUF_CREDITS);
CleanupStack::PushL(desArray);
edwin->SetTextLimit(2048); // to prevent stupid "too big" warning
TInt count = desArray->Count();
for (TInt i = 0; i < count; i++)
{
edwin->Text()->InsertL(edwin->TextLength(), desArray->operator[](i));
edwin->Text()->InsertL(edwin->TextLength(), CEditableText::ELineBreak);
}
CleanupStack::PopAndDestroy(desArray);
}
TKeyResponse CCreditsDialog::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
if (aType == EEventKey)
{
CEikEdwin *edwin = LocateControlByUniqueHandle<CEikEdwin>(ECtlPicoCreditsText);
User::LeaveIfNull(edwin);
if (aKeyEvent.iCode == EQuartzKeyTwoWayDown)
{
edwin->MoveDisplayL(TCursorPosition::EFLineDown);
edwin->UpdateScrollBarsL();
return EKeyWasConsumed;
}
else if (aKeyEvent.iCode == EQuartzKeyTwoWayUp)
{
edwin->MoveDisplayL(TCursorPosition::EFLineUp);
edwin->UpdateScrollBarsL();
return EKeyWasConsumed;
}
}
return CQikSimpleDialog::OfferKeyEventL(aKeyEvent, aType);
}
/*************************************************************
*
* Debug dialog
*
**************************************************************/
CDebugDialog::CDebugDialog(char *t)
{
Mem::Copy(iText, t, 1024);
iText[1023] = 0;
}
void CDebugDialog::PreLayoutDynInitL()
{
char *p = iText, *line = iText;
TBool end=0;
TBuf<128> tbuf;
CEikEdwin *editor = LocateControlByUniqueHandle<CEikEdwin>(ECtlPicoCreditsText);
while(!end) {
while(*p && *p != '\r' && *p != '\n') p++;
if(!*p) end=1;
*p = 0;
TPtrC8 ptr((TUint8*) line);
tbuf.Copy(ptr);
editor->Text()->InsertL(editor->TextLength(), tbuf);
editor->Text()->InsertL(editor->TextLength(), CEditableText::ELineBreak);
line = ++p;
}
}

View file

@ -1,94 +0,0 @@
/*******************************************************************
*
* File: Dialogs.h
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2002, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#ifndef __DIALOGS_H
#define __DIALOGS_H
#include <eikenv.h>
#include <eikdialg.h>
#include <eiktxlbx.h>
#include <eiktxlbm.h>
#include <eikdlgtb.h>
#include <eiklabel.h>
#include <eikchlst.h>
#include <eikchkbx.h>
#include <eikedwob.h>
#include <qiksimpledialog.h>
/************************************************
*
* config Dialog
*
************************************************/
extern "C" struct _currentConfig_t;
class CPicoConfigDialog : public CEikDialog
{
public:
CPicoConfigDialog(_currentConfig_t &cfg);
protected: // framework
void PostLayoutDynInitL();
void HandleControlStateChangeL(TInt aControlId);
TBool OkToExitL(TInt aButtonId);
_currentConfig_t &config;
};
/************************************************
*
* About Dialog
*
************************************************/
class CAboutDialog : public CQikSimpleDialog
{
protected: // from CQikSimpleDialog
void PostLayoutDynInitL();
};
/*************************************************************
*
* Credits dialog
*
**************************************************************/
class CCreditsDialog : public CQikSimpleDialog
{
protected: // from CQikSimpleDialog
void PreLayoutDynInitL();
TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
};
/*************************************************************
*
* Debug dialog
*
**************************************************************/
class CDebugDialog : public CCreditsDialog
{
public:
CDebugDialog(char *t);
protected:
char iText[1024];
void PreLayoutDynInitL();
};
#endif // __DIALOGS_H

View file

@ -1,352 +0,0 @@
/*******************************************************************
*
* File: Engine.cpp
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2002, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#include "Engine.h"
#include <w32std.h>
#include <eikenv.h>
#include <e32svr.h>
#include <e32math.h>
#include <e32uid.h>
#include <string.h>
#include "version.h"
#include <pico/pico_int.h>
#include "../common/emu.h"
#include "engine/debug.h"
#include "App.h"
// this is where we start to break a bunch of symbian rules
extern TInt machineUid;
extern int gamestate, gamestate_next;
extern char *loadrom_fname;
extern int loadrom_result;
extern const char *actionNames[];
RSemaphore initSemaphore;
RSemaphore pauseSemaphore;
RSemaphore loadWaitSemaphore;
static CPicolAppView *appView = 0;
TInt CPicoGameSession::Do(const TPicoServRqst what, TAny *param)
{
switch (what)
{
case PicoMsgLoadState:
if(!rom_loaded) return -1; // no ROM
return emu_save_load_game(1, 0);
case PicoMsgSaveState:
if(!rom_loaded) return -1;
return emu_save_load_game(0, 0);
case PicoMsgLoadROM:
return loadROM((TPtrC16 *)param);
case PicoMsgResume:
DEBUGPRINT(_L("resume"));
if(rom_loaded) {
return ChangeRunState(PGS_Running);
}
return 1;
case PicoMsgReset:
if(rom_loaded) {
return ChangeRunState(PGS_Reset);
}
return 1;
case PicoMsgKeys:
return ChangeRunState(PGS_KeyConfig);
case PicoMsgPause:
return ChangeRunState(PGS_Paused);
case PicoMsgQuit:
DEBUGPRINT(_L("got quit msg."));
return ChangeRunState(PGS_Quit);
// config change
case PicoMsgConfigChange:
return changeConfig((TPicoConfig *)param);
case PicoMsgSetAppView:
appView = (CPicolAppView *)param;
return 1;
default:
return 1;
}
}
TInt EmuThreadFunction(TAny* anArg);
TInt CPicoGameSession::StartEmuThread()
{
TInt res=KErrNone;
iEmuRunning = EFalse;
if (initSemaphore.Handle() > 0)
initSemaphore.Close();
initSemaphore.CreateLocal(0);
if (pauseSemaphore.Handle() <= 0)
pauseSemaphore.CreateLocal(0);
if (loadWaitSemaphore.Handle() <= 0)
loadWaitSemaphore.CreateLocal(0);
RThread thread;
if(iThreadWatcher && (res = thread.Open(iThreadWatcher->iTid)) == KErrNone) {
// should be a dead thread in some strange state.
DEBUGPRINT(_L("found thread with the same id (id=%i, RequestCount=%i), killing.."),
(TInt32)thread.Id(), thread.RequestCount());
// what can we do in this situation? Nothing seems to help, it just stays in this state.
delete iThreadWatcher;
iThreadWatcher = 0;
thread.Kill(1);
thread.Terminate(1);
thread.Close();
}
res=thread.Create(_L("PicoEmuThread"), // create new server thread
EmuThreadFunction, // thread's main function
KDefaultStackSize,
KMinHeapSize,
KPicoMaxHeapSize,
0 // &semaphore // passed as TAny* argument to thread function
);
if(res == KErrNone) { // thread created ok - now start it going
thread.SetPriority(EPriorityMore);
iEmuRunning = ETrue;
if (iThreadWatcher) delete iThreadWatcher;
iThreadWatcher = CThreadWatcher::NewL(thread.Id());
thread.Resume(); // start it going
DEBUGPRINT(_L("initSemaphore.Wait()"));
res = initSemaphore.Wait(3*1000*1000); // wait until it's initialized
DEBUGPRINT(_L("initSemaphore resume, ExitReason() == %i"), thread.ExitReason());
res |= thread.ExitReason();
thread.Close(); // we're no longer interested in the other thread
if(res != KErrNone) iEmuRunning = EFalse;
return res;
}
return res;
}
TInt CPicoGameSession::ChangeRunState(TPicoGameState newstate, TPicoGameState newstate_next)
{
if (!iEmuRunning) {
gamestate = PGS_Paused;
TInt res = StartEmuThread();
if(res != KErrNone) DEBUGPRINT(_L("StartEmuThread() returned %i"), res);
if (!iEmuRunning) return PicoErrEmuThread;
}
int oldstate = gamestate;
gamestate = newstate;
gamestate_next = newstate_next ? newstate_next : PGS_Paused;
if (oldstate == PGS_Paused) pauseSemaphore.Signal();
return 0;
}
TInt CPicoGameSession::loadROM(TPtrC16 *pptr)
{
TInt ret;
char buff[150];
// make sure emu thread is ok
ret = ChangeRunState(PGS_Paused);
if(ret) return ret;
// read the contents of the client pointer into a TPtr.
static TBuf8<KMaxFileName> writeBuf;
writeBuf.Copy(*pptr);
// push the emu thead to a load state. This is done so that it owns all file handles.
// If successful, in will enter PGS_Running state by itself.
loadrom_fname = (char *)writeBuf.PtrZ();
loadrom_result = 0;
loadWaitSemaphore.Wait(1); // make sure sem is not set
ret = ChangeRunState(PGS_ReloadRom);
if(ret) return ret;
loadWaitSemaphore.Wait(60*1000*1000);
if (loadrom_result == 0)
return PicoErrRomOpenFailed;
emu_get_game_name(buff);
TPtrC8 buff8((TUint8*) buff);
iRomInternalName.Copy(buff8);
DEBUGPRINT(_L("done waiting for ROM load"));
// debug
#ifdef __DEBUG_PRINT
TInt mem, cells = User::CountAllocCells();
User::AllocSize(mem);
DEBUGPRINT(_L("comm: cels=%d, size=%d KB"), cells, mem/1024);
#endif
return 0;
}
TInt CPicoGameSession::changeConfig(TPicoConfig *aConfig)
{
// 6 button pad, enable XYZM config if needed
if (PicoOpt & POPT_6BTN_PAD)
{
actionNames[8] = "Z";
actionNames[9] = "Y";
actionNames[10] = "X";
actionNames[11] = "MODE";
} else {
actionNames[8] = actionNames[9] = actionNames[10] = actionNames[11] = 0;
}
// if we are in center 90||270 modes, we can bind renderer switcher
if (currentConfig.scaling == TPicoConfig::PMFit &&
(currentConfig.rotation == TPicoConfig::PRot0 || currentConfig.rotation == TPicoConfig::PRot180))
actionNames[25] = 0;
else actionNames[25] = "RENDERER";
return 0;
}
#ifdef __DEBUG_PRINT_FILE
extern RMutex logMutex;
#endif
void CPicoGameSession::freeResources()
{
RThread thread;
TInt i;
DEBUGPRINT(_L("CPicoGameSession::freeResources()"));
if(iThreadWatcher && thread.Open(iThreadWatcher->iTid) == KErrNone)
{
// try to stop our emu thread
gamestate = PGS_Quit;
if(pauseSemaphore.Handle() > 0)
pauseSemaphore.Signal();
if(thread.Handle() > 0)
{
// tried reopening thread handle here over time intervals to detect if thread is alive,
// but would run into handle panics.
for(i = 0; i < 8; i++) {
User::After(100 * 1000);
if(thread.ExitReason() != 0) break;
}
if(thread.ExitReason() == 0) {
// too late, time to die
DEBUGPRINT(_L("thread %i not responding, killing.."), (TInt32) thread.Id());
thread.Terminate(1);
}
thread.Close();
}
}
if (iThreadWatcher != NULL)
{
DEBUGPRINT(_L("delete iThreadWatcher"));
delete iThreadWatcher;
DEBUGPRINT(_L("after delete iThreadWatcher"));
iThreadWatcher = NULL;
}
if (initSemaphore.Handle() > 0)
initSemaphore.Close();
if (pauseSemaphore.Handle() > 0)
pauseSemaphore.Close();
if (loadWaitSemaphore.Handle() > 0)
loadWaitSemaphore.Close();
DEBUGPRINT(_L("freeResources() returning"));
#ifdef __DEBUG_PRINT_FILE
if (logMutex.Handle() > 0)
logMutex.Close();
#endif
}
TBool CPicoGameSession::iEmuRunning = EFalse;
CThreadWatcher *CPicoGameSession::iThreadWatcher = 0;
TBuf<150> CPicoGameSession::iRomInternalName;
// CThreadWatcher
CThreadWatcher::~CThreadWatcher()
{
Cancel();
DEBUGPRINT(_L("after CThreadWatcher::Cancel();"));
}
CThreadWatcher::CThreadWatcher(const TThreadId& aTid)
: CActive(CActive::EPriorityStandard), iTid(aTid)
{
}
CThreadWatcher* CThreadWatcher::NewL(const TThreadId& aTid)
{
CThreadWatcher* self = new(ELeave) CThreadWatcher(aTid);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(); // self
return self;
}
void CThreadWatcher::ConstructL()
{
CActiveScheduler::Add(this);
RThread thread;
if(thread.Open(iTid) == KErrNone) {
thread.Logon(iStatus);
thread.Close();
SetActive();
}
}
void CThreadWatcher::RunL()
{
DEBUGPRINT(_L("CThreadWatcher::RunL()"));
CPicoGameSession::iEmuRunning = EFalse;
if(appView) appView->UpdateCommandList();
//initSemaphore.Signal(); // no point to do that here, AS can't get here if it is waiting
}
void CThreadWatcher::DoCancel()
{
RThread thread;
DEBUGPRINT(_L("CThreadWatcher::DoCancel()"));
if(thread.Open(iTid) == KErrNone) {
DEBUGPRINT(_L("thread.LogonCancel(iStatus);"));
thread.LogonCancel(iStatus);
thread.Close();
}
}
extern "C" void cache_flush_d_inval_i(const void *start_addr, const void *end_addr)
{
// TODO
User::IMB_Range((TAny *)start_addr, (TAny *)end_addr);
}

View file

@ -1,143 +0,0 @@
/*******************************************************************
*
* File: Engine.h
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2002, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#ifndef __ENGINE_H
#define __ENGINE_H
#include <e32base.h>
class RReadStream;
class RWriteStream;
// engine states
enum TPicoGameState {
PGS_Running = 1,
PGS_Paused,
PGS_Quit,
PGS_KeyConfig,
PGS_ReloadRom,
PGS_Reset,
};
enum TPicoServRqst {
PicoMsgLoadState,
PicoMsgSaveState,
PicoMsgLoadROM,
PicoMsgResume,
PicoMsgReset,
PicoMsgKeys,
PicoMsgPause,
PicoMsgQuit,
PicoMsgConfigChange,
PicoMsgSetAppView,
kDefaultMessageSlots // this is how many messages we need :)
};
enum TPicoGenErrors { // generic errors
PicoErrNoErr = 0, // OK
PicoErrRomOpenFailed,
PicoErrOutOfMem,
PicoErrOutOfMemSnd,
PicoErrGenSnd, // generic sound system error
PicoErrEmuThread
};
// needed for creating server thread.
const TUint KPicoMaxHeapSize=0x00800000;
// key config entry (touchpad areas)
struct TPicoAreaConfigEntry {
TRect rect;
//unsigned long actions;
};
struct TPicoKeyConfigEntry
{
unsigned short keyCode;
unsigned char scanCode;
unsigned char flags; // lsb->msb: key_down, pulse_only, ?, ?, ?, ?, not_configurable, disabled
TInt32 handle1; // for CancelCaptureKeyUpAndDowns()
TInt32 handle2; // for CancelCaptureKey()
char *name;
};
// configuration data
class TPicoConfig
{
public:
// void SetDefaults();
// void InternalizeL(RReadStream &aStream);
// void ExternalizeL(RWriteStream &aStream) const;
enum TPicoScreenRotation {
PRot0,
PRot90,
PRot180,
PRot270
};
enum TPicoScreenMode {
PMCenter,
PMFit,
PMFit2
};
enum TPicoFrameSkip {
PFSkipAuto = -1,
PFSkip0
};
public:
TFileName iLastROMFile; // used as tmp only
};
class CThreadWatcher : public CActive
{
public:
static CThreadWatcher* NewL(const TThreadId& aTid);
~CThreadWatcher();
TThreadId iTid; // thread id
protected:
CThreadWatcher(const TThreadId& aTid);
void ConstructL();
virtual void RunL();
virtual void DoCancel();
};
class CPicoGameSession
{
public:
static TInt Do(const TPicoServRqst what, TAny *param=0);
static void freeResources();
static TBool iEmuRunning;
static TBuf<150> iRomInternalName;
private:
// services available
static TInt StartEmuThread();
static TInt ChangeRunState(TPicoGameState newstate, TPicoGameState newstate_next=(TPicoGameState)0);
static TInt loadROM(TPtrC16 *pptr);
static TInt changeConfig(TPicoConfig *aConfig);
static CThreadWatcher *iThreadWatcher;
};
#endif

View file

@ -1,133 +0,0 @@
# makefile for uiq3_patcher_0_2.tar.gz setup, modified
export CROSS = arm-none-symbianelf-
APPNAME = PicoDrive
VER_MAJ = 1
VER_MIN = 51
VENDOR = notaz
UID3 = A00010F3
EPOCROOT = /opt/uiq3/
EPOCLIBS = qikdlg.lib etext.lib bafl.lib efsrv.lib eikctl.lib ws32.lib \
eikdlg.lib gdi.lib estor.lib hal.lib mediaclient.lib mediaclientaudiostream.lib
STACK = 0x3000
HEAP = 0x10,0x1000000
# settings
asm_memory = 1
asm_render = 1
asm_ym2612 = 1
asm_misc = 1
asm_cdpico = 1
asm_cdmemory = 1
asm_blit = 1
use_cyclone = 1
#use_musashi = 1
# objects
# launcher
OBJS += App.o Engine.o Dialogs.o CSimpleTextParser.o emu.o
# engine
OBJS += engine/main.o engine/vid.o engine/polledas.o engine/audio_mediaserver.o engine/debug.o
ifeq "$(asm_blit)" "1"
OBJS += engine/blit_asm.o
else
OBJS += engine/blit.o
endif
# common
OBJS += ../common/emu.o ../common/config.o ../common/menu.o ../common/mp3_helix.o
# Pico
OBJS += pico/area.o pico/cart.o pico/memory.o pico/misc.o pico/pico.o pico/sek.o \
pico/videoport.o pico/draw2.o pico/draw.o pico/patch.o pico/debug.o
# Pico - CD
OBJS += pico/cd/pico.o pico/cd/memory.o pico/cd/sek.o pico/cd/LC89510.o \
pico/cd/cd_sys.o pico/cd/cd_file.o pico/cd/cue.o pico/cd/gfx_cd.o \
pico/cd/area.o pico/cd/misc.o pico/cd/pcm.o pico/cd/buffering.o
# Pico - Pico
OBJS += pico/pico/pico.o pico/pico/memory.o pico/pico/xpcm.o
# Pico - carthw
OBJS += pico/carthw/carthw.o pico/carthw/svp/svp.o pico/carthw/svp/memory.o \
pico/carthw/svp/ssp16.o pico/carthw/svp/compiler.o pico/carthw/svp/stub_arm.o
# Pico - sound
OBJS += pico/sound/sound.o
OBJS += pico/sound/mix_arm.o
OBJS += pico/sound/sn76496.o pico/sound/ym2612.o
# zlib
OBJS += zlib/gzio.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o \
zlib/deflate.o zlib/crc32.o zlib/adler32.o zlib/zutil.o zlib/compress.o
# unzip
OBJS += unzip/unzip.o unzip/unzip_stream.o
# CPU cores
ifeq "$(use_musashi)" "1"
CFLAGS += -DEMU_M68K
OBJS += cpu/musashi/m68kops.o cpu/musashi/m68kcpu.o
endif
ifeq "$(use_cyclone)" "1"
CFLAGS += -DEMU_C68K
OBJS += cpu/Cyclone/proj/Cyclone.o cpu/Cyclone/tools/idle.o
endif
# drz80
CFLAGS += -D_USE_DRZ80
OBJS += cpu/DrZ80/drz80.o
# helix
OBJS += ../common/helix/$(CROSS)helix-mp3.a
vpath %.c = ../..
vpath %.s = ../..
vpath %.S = ../..
DIRS = platform platform/common pico pico/cd pico/pico pico/sound pico/carthw/svp \
zlib unzip cpu cpu/musashi cpu/Cyclone/proj cpu/Cyclone/tools cpu/mz80 cpu/DrZ80
ICONS := $(shell echo rsc/*.bmp)
APPICON = $(NAME).mbm
RSCDIR = rsc
REGDIR = rsc
CFLAGS += -I./ -I../../
CFLAGS += -DUIQ3 -DARM -DNO_SYNC
CFLAGS += -D__DEBUG_PRINT
CFLAGS += -mcpu=arm926ej-s -mtune=arm926ej-s -O3 -ftracer \
-fstrength-reduce -fomit-frame-pointer -fstrict-aliasing -ffast-math
SFLAGS = -march=armv5t -msoft-float -nostdinc
ASFLAGS = -mcpu=arm926ej-s -mfloat-abi=soft
export CFLAGS
SRCRES := $(shell echo rsc/*.rss)
EPOCRCFLAGS += -I./
all: mkdirs sis
include ../common/common_arm.mak
include uiq3.mak
$(NAME).mbg $(NAME).mbm : $(ICONS)
@echo "Creating multibitmap file..."
$(BMCONV) /h$(NAME).mbg $(NAME).mbm \
/c24rsc/pico18x18.bmp /8rsc/pico18x18m.bmp \
/c24rsc/pico40x40.bmp /8rsc/pico40x40m.bmp \
/c24rsc/pico64x64.bmp /8rsc/pico64x64m.bmp
engine/blit_asm.o : engine/blit.s
@echo ">>>" $@
$(AS) $(ASFLAGS) $< -o $@
readme.txt: ../../tools/textfilter ../base_readme.txt
../../tools/textfilter ../base_readme.txt $@ UIQ
# ----------- release -----------
ifneq ($(findstring rel,$(MAKECMDGOALS)),)
ifeq ($(VER),)
$(error need VER)
endif
endif
rel: picodrive.sis readme.txt
zip -9 -j ../../PicoDrive_uiq3_$(VER).zip $^
mkdir bin_to_cso_mp3
cp ../../tools/bin_to_cso_mp3/* bin_to_cso_mp3/
zip -9 -r ../../PicoDrive_uiq3_$(VER).zip bin_to_cso_mp3
rm -rf bin_to_cso_mp3

View file

@ -1,307 +0,0 @@
# makefile for GCCE
# settings
#dprint = 1
asm_memory = 1
asm_render = 1
asm_blit = 1
#use_musashi = 1
#up = 1
#sis = 1
# targets
all: $(EPOCROOT2)epoc32 MAKEDIRS RESOURCES PicoDrive.exe
clean :
@perl -S ermdir.pl _build
@erase 2>>nul rsc\*.rsc
@erase 2>>nul rsc\*.rsg
@erase 2>>nul rsc\PicoDrive.mb?
# paths
$(EPOCROOT2)epoc32 :
@echo Please set EPOCROOT2 environmental variable to full path to your SDK
@echo with ending slash (something like C:\Uiq_21\)
@cd : 2> NUL # do something stupid to make it silently fail
# resource compiler hates drive lettered paths
EPOCROOT2_NODRV = $(filter \\%,$(subst :, ,$(EPOCROOT2)))
EPOCLIB = $(EPOCROOT2)EPOC32\RELEASE\ARMV5
# C/C++ Compiler
CC=arm-none-symbianelf-gcc
# Linker
LD=arm-none-symbianelf-ld
# Assembler
ASM=arm-none-symbianelf-as
# Archiver
AR=arm-none-symbianelf-ar
# Strip
STRIP=arm-none-symbianelf-strip
# gcc config
GCCDEFINES = -DNDEBUG -D_UNICODE -D__GCCE__ -D__SYMBIAN32__ -D__EPOC32__ -D__MARM__ \
-D__EABI__ -D__MARM_ARMV5__ -D__EXE__ -D__SUPPORT_CPP_EXCEPTIONS__ \
-D__MARM_ARMV5__ -D__PRODUCT_INCLUDE__=\"$(EPOCROOT2)epoc32/include/variant/UIQ_3.0.hrh\"
GCCDEFINES += -D_UNZIP_SUPPORT -D__BROKEN_FWRITE
# 'CSL Arm Toolchain' stuff must be specified after Symbian includes
GCCINCLUDES = -I "$(EPOCROOT2)epoc32\include\variant" -I "$(EPOCROOT2)EPOC32\INCLUDE" -I "$(EPOCROOT2)EPOC32\INCLUDE\LIBC" \
-I "$(EPOCROOT2)\CSL Arm Toolchain\lib\gcc\arm-none-symbianelf\3.4.3\include" -I.
# -funit-at-a-time is not compatible with SDK, it either has linker problems or does not start on device
GCCCOMMFLAGS = -Wall -Wno-unknown-pragmas -fexceptions -march=armv5t -mapcs -pipe -nostdinc -msoft-float \
$(GCCINCLUDES) -include "$(EPOCROOT2)EPOC32/INCLUDE/GCCE/GCCE.h" -marm
GCCCPPFLAGS = -x c++ -Wno-ctor-dtor-privacy -O3 -fno-unit-at-a-time
GCCCFLAGS = -x c -O3 -fno-unit-at-a-time
GCCLDFLAGS = -L"$(EPOCROOT2)CSL Arm Toolchain\arm-none-symbianelf\lib" \
-L"$(EPOCROOT2)CSL Arm Toolchain\lib\gcc\arm-none-symbianelf\3.4.3" \
--target1-abs --no-undefined -nostdlib -shared -Ttext 0x8000 -Tdata 0x400000 --default-symver
# libs
LIBS = \
$(EPOCLIB)\LIB\ESTLIB.dso \
$(EPOCLIB)\urel\qikalloc.lib \
$(EPOCLIB)\LIB\euser.dso \
$(EPOCLIB)\LIB\apparc.dso \
$(EPOCLIB)\LIB\cone.dso \
$(EPOCLIB)\LIB\eikcore.dso \
$(EPOCLIB)\LIB\eikcoctl.dso \
$(EPOCLIB)\LIB\qikcore.dso \
$(EPOCLIB)\LIB\qikdlg.dso \
$(EPOCLIB)\LIB\etext.dso \
$(EPOCLIB)\LIB\bafl.dso \
$(EPOCLIB)\LIB\efsrv.dso \
$(EPOCLIB)\LIB\eikctl.dso \
$(EPOCLIB)\LIB\WS32.dso \
$(EPOCLIB)\LIB\EIKDLG.dso \
$(EPOCLIB)\LIB\GDI.dso \
$(EPOCLIB)\LIB\estor.dso \
$(EPOCLIB)\LIB\EZLIB.dso \
$(EPOCLIB)\LIB\HAL.dso \
$(EPOCLIB)\LIB\mediaclient.dso \
$(EPOCLIB)\LIB\mediaclientaudiostream.dso
LIBS += \
$(EPOCLIB)\LIB\qikallocdll.dso \
$(EPOCLIB)\UREL\usrt2_2.lib \
$(EPOCLIB)\LIB\dfpaeabi.dso \
$(EPOCLIB)\LIB\dfprvct2_2.dso \
$(EPOCLIB)\LIB\drtaeabi.dso \
$(EPOCLIB)\LIB\scppnwdl.dso \
$(EPOCLIB)\LIB\drtrvct2_2.dso
# objects
# launcher
OBJECTS += _build\App.o _build\Engine.o _build\Dialogs.o _build\CSimpleTextParser.o
# engine
OBJECTS += _build\main.o _build\vid.o _build\polledas.o _build\audio_mediaserver.o _build\debug.o
# Pico
OBJECTS += _build\Area.o _build\Cart.o _build\Utils.o _build\Memory.o _build\Misc.o \
_build\Pico.o _build\Sek.o _build\VideoPort.o _build\Draw2.o _build\Draw.o
# asm stuff
ifeq "$(asm_render)" "1"
GCCDEFINES += -D_ASM_DRAW_C
OBJECTS += _build\draw_asm.o _build\draw2_asm.o
endif
ifeq "$(asm_memory)" "1"
GCCDEFINES += -D_ASM_MEMORY_C
OBJECTS += _build\memory_asm.o
endif
# Pico - sound
OBJECTS += _build\sound.o _build\sn76496.o _build\ym2612.o
# misc
OBJECTS += _build\unzip.o _build\gzio_symb.o
# CPU cores
ifeq "$(use_musashi)" "1"
GCCDEFINES += -DEMU_M68K
OBJECTS += _build\m68kcpu.o _build\m68kopac.o _build\m68kopdm.o _build\m68kopnz.o _build\m68kops.o
else
GCCDEFINES += -DEMU_C68K
OBJECTS += _build\Cyclone.o
endif
ifeq "$(asm_blit)" "1"
OBJECTS += _build\blit_asm.o
else
OBJECTS += _build\blit.o
endif
GCCDEFINES += -D_USE_DRZ80
OBJECTS += _build\DrZ80.o
GCCDEFINES += -D_ASM_YM2612_C
OBJECTS += _build\ym2612_asm.o
# dprint
ifeq "$(dprint)" "1"
GCCDEFINES += -D__DEBUG_PRINT
endif
define crule
@echo * $<
@$(CC) -c $(GCCCOMMFLAGS) $(GCCDEFINES) $(GCCCFLAGS) $< -o $@
endef
define cpprule
@echo * $<
@$(CC) -c $(GCCCOMMFLAGS) $(GCCDEFINES) $(GCCCPPFLAGS) $< -o $@
endef
define asmrule
@echo * $<
@$(ASM) -marmv4t -mthumb-interwork -o $@ $^
endef
# object making rules
_build\App.o : App.cpp
$(cpprule)
_build\Engine.o : Engine.cpp
$(cpprule)
_build\Dialogs.o : Dialogs.cpp
$(cpprule)
_build\CSimpleTextParser.o : CSimpleTextParser.cpp
$(cpprule)
_build\main.o : engine\main.cpp
$(cpprule)
_build\vid.o : engine\vid.cpp
$(cpprule)
_build\polledas.o: engine\polledas.cpp
$(cpprule)
_build\audio_mediaserver.o : engine\audio_mediaserver.cpp
$(cpprule)
_build\debug.o : engine\debug.cpp
$(cpprule)
_build\blit.o : engine\blit.c
$(crule)
_build\Area.o : ..\..\Pico\Area.c
$(crule)
_build\Cart.o : ..\..\Pico\Cart.c
$(crule)
_build\Draw.o : ..\..\Pico\Draw.c
$(crule)
_build\Draw2.o : ..\..\Pico\Draw2.c
$(crule)
_build\Memory.o : ..\..\Pico\Memory.c
$(crule)
_build\Misc.o : ..\..\Pico\Misc.c
$(crule)
_build\Pico.o : ..\..\Pico\Pico.c
$(crule)
_build\Sek.o : ..\..\Pico\Sek.c
$(crule)
_build\Utils.o : ..\..\Pico\Utils.c
$(crule)
_build\VideoPort.o : ..\..\Pico\VideoPort.c
$(crule)
_build\sound.o : ..\..\Pico\sound\sound.c
$(crule)
_build\sn76496.o : ..\..\Pico\sound\sn76496.c
$(crule)
_build\ym2612.o : ..\..\Pico\sound\ym2612.c
$(crule)
_build\unzip.o : ..\..\unzip\unzip.c
$(crule)
_build\gzio_symb.o : ..\..\zlib\gzio_symb.c
$(crule)
_build\m68kcpu.o : ..\..\musashi\m68kcpu.c
$(crule)
_build\m68kopac.o : ..\..\musashi\m68kopac.c
$(crule)
_build\m68kopdm.o : ..\..\musashi\m68kopdm.c
$(crule)
_build\m68kopnz.o : ..\..\musashi\m68kopnz.c
$(crule)
_build\m68kops.o : ..\..\musashi\m68kops.c
$(crule)
_build\Cyclone.o : ..\..\cpu\Cyclone\proj\Cyclone.s
$(asmrule)
_build\DrZ80.o : ..\..\cpu\DrZ80\drz80.s
$(asmrule)
_build\draw_asm.o : ..\..\Pico\draw.s
$(asmrule)
_build\draw2_asm.o : ..\..\Pico\draw2.s
$(asmrule)
_build\memory_asm.o : ..\..\Pico\memory.s
$(asmrule)
_build\ym2612_asm.o : ..\..\Pico\sound\ym2612.s
$(asmrule)
_build\blit_asm.o : engine\blit.s
$(asmrule)
PicoDrive.exe : $(OBJECTS)
@echo * ld
@$(LD) $(GCCLDFLAGS) -soname PicoDrive{000a0000}[a00010f3].exe --entry _E32Startup -u _E32Startup \
$(EPOCROOT2)EPOC32\RELEASE\ARMV5\UREL\EEXE.LIB -o "_build\PicoDrive_elf.exe" -Map "_build\PicoDrive.exe.map" $(OBJECTS) $(LIBS) -lsupc++ -lgcc
# @echo * strip
# @$(STRIP) _build\PicoDrive_elf.exe
@echo * elf2e32
@elf2e32 --sid=0xa00010f3 --heap=0x00000100,0x00800000 --stack=0x00003000 \
--uid1=0x1000007a --uid2=0x100039ce --uid3=0xa00010f3 \
--capability=none --fpu=softvfp --targettype=EXE --output="$@" \
--elfinput="_build\PicoDrive_elf.exe" --linkas=PicoDrive{000a0000}[a00010f3].exe --libpath="$(EPOCLIB)\LIB"
ifeq "$(sis)" "1"
@make -C _out
ifeq "$(up)" "1"
@qup.cmd
endif
endif
MAKEDIRS : _build
_build :
# @echo * making build dir
@perl -S emkdir.pl $@
# BitMap PicoDrive.mbm
RESOURCES : rsc\PicoDrive.mbm rsc\PicoDrive.RSC rsc\PicoDrive_reg.RSC rsc\PicoDrive_loc.RSC rsc\PicoDrive.mbg
rsc\PicoDrive.mbg : rsc\PicoDrive.mbm
rsc\PicoDrive.mbm : rsc\pico18x18.bmp rsc\pico18x18m.bmp rsc\pico40x40.bmp rsc\pico40x40m.bmp rsc\pico64x64.bmp rsc\pico64x64m.bmp
@echo * $@
@perl -S epocmbm.pl -h"rsc\PicoDrive.mbg" -o"rsc\PicoDrive.mbm" -l"\Z\Resource\Apps\:rsc" \
-b"/c24rsc\pico18x18.bmp /8rsc\pico18x18m.bmp /c24rsc\pico40x40.bmp /8rsc\pico40x40m.bmp /c24rsc\pico64x64.bmp /8rsc\pico64x64m.bmp" -l"\Z\Resource\Apps\:rsc"
@perl -S ecopyfile.pl "rsc\PicoDrive.mbg" "$(EPOCROOT2)EPOC32\INCLUDE\PicoDrive.mbg"
# Resource Z\Resource\Apps\PicoDrive.RSC
rsc\PicoDrive.RSC : rsc\PicoDrive.rss picodrive.hrh
@echo * $@
@perl -S epocrc.pl -m045,046,047 -I "." -I- -I "$(EPOCROOT2_NODRV)EPOC32\include" -DLANGUAGE_SC -u "rsc\PicoDrive.rss" -o$@ \
-h"rsc\PicoDrive.rsg" -t"rsc" -l"Z\Resource\Apps:rsc"
@perl -S ecopyfile.pl "rsc\PicoDrive.rsg" "$(EPOCROOT2)EPOC32\INCLUDE\PicoDrive.RSG"
# Resource Z\private\10003a3f\apps\PicoDrive_reg.RSC
rsc\PicoDrive_reg.RSC : rsc\PicoDrive_reg.rss
@echo * $@
@perl -S epocrc.pl -m045,046,047 -I "." -I- -I "$(EPOCROOT2)EPOC32\include" -DLANGUAGE_SC -u "rsc\PicoDrive_reg.rss" -o$@ \
-t"rsc" -l"Z\private\10003a3f\apps:rsc"
# Resource Z\Resource\Apps\PicoDrive_loc.RSC
rsc\PicoDrive_loc.RSC : rsc\PicoDrive_loc.rss
@echo * $@
@perl -S epocrc.pl -m045,046,047 -I "." -I- -I "$(EPOCROOT2)EPOC32\include" -DLANGUAGE_SC -u "rsc\PicoDrive_loc.rss" -o$@ \
-t"rsc" -l"Z\Resource\Apps:rsc"

View file

@ -1,140 +0,0 @@
TARGET PicoDrive.exe
TARGETTYPE exe
//TARGETPATH ?
UID 0x100039CE 0xA00010F3
EPOCSTACKSIZE 0x3000 // required by CQikSelectFileDlg
EPOCHEAPSIZE 0x100 0x00800000 // required by large ROMs :)
// resource
SOURCEPATH Rsc
START RESOURCE PicoDrive.rss
HEADER
TARGETPATH \Resource\Apps
LANG SC
END
START RESOURCE PicoDrive_reg.rss
TARGETPATH \private\10003a3f\apps
END
START RESOURCE PicoDrive_loc.rss
TARGETPATH \Resource\Apps
LANG SC
END
CAPABILITY none // SwEvent // forbidden
USERINCLUDE ..\..
SYSTEMINCLUDE \epoc32\include
SYSTEMINCLUDE \epoc32\include\libc
// launcher
SOURCEPATH .
SYSTEMINCLUDE . // for port_config.h
SOURCE App.cpp
SOURCE Engine.cpp
SOURCE Dialogs.cpp
SOURCE CSimpleTextParser.cpp
// engine
SOURCEPATH engine
SOURCE main.cpp
SOURCE vid.cpp
SOURCE polledas.cpp
SOURCE debug.cpp
SOURCE audio_mediaserver.cpp
SOURCE blit.c
// pico
MACRO _UNZIP_SUPPORT
SOURCEPATH ..\..\Pico
USERINCLUDE ..\..\Pico
SOURCE Area.c
SOURCE Cart.c
SOURCE Draw.c
SOURCE Draw2.c
SOURCE Memory.c
SOURCE Misc.c
SOURCE Pico.c
SOURCE Sek.c
SOURCE Utils.c
SOURCE VideoPort.c
// pico - sound
SOURCEPATH ..\..\Pico\Sound
SOURCE sound.c
SOURCE sn76496.c
SOURCE ym2612.c
// CPU cores
MACRO EMU_M68K
SOURCEPATH ..\..\cpu\Musashi
USERINCLUDE ..\..\cpu\Musashi
SOURCE m68kcpu.c
SOURCE m68kopac.c
SOURCE m68kopdm.c
SOURCE m68kopnz.c
SOURCE m68kops.c
//MACRO _USE_MZ80
//SOURCEPATH ..\win32\z80
//SOURCE mz80_asm.obj
// misc
SOURCEPATH ..\..\unzip
USERINCLUDE ..\..\unzip
SOURCE unzip.c
SOURCEPATH ..\..\zlib
USERINCLUDE ..\..\zlib
SOURCE gzio_symb.c
// TODO: get rid of unneeded stuff
LIBRARY ESTLIB.LIB
LIBRARY euser.lib
LIBRARY apparc.lib
LIBRARY cone.lib
LIBRARY eikcore.lib
LIBRARY eikcoctl.lib
LIBRARY qikcore.lib
LIBRARY qikdlg.lib // CQikSelectFileDlg
LIBRARY etext.lib // TCharFormat
LIBRARY bafl.lib // CDesCArrayFlat
LIBRARY efsrv.lib
LIBRARY eikctl.lib
LIBRARY WS32.LIB
LIBRARY EIKDLG.LIB
//LIBRARY EGUL.LIB // CColorList
LIBRARY GDI.LIB // TTypeface
LIBRARY estor.lib // RWriteStream
LIBRARY EZLIB.LIB
LIBRARY HAL.LIB
LIBRARY mediaclient.LIB
LIBRARY mediaclientaudiostream.LIB
STATICLIBRARY qikalloc.lib
LIBRARY qikallocdll.lib
MACRO __DEBUG_PRINT
MACRO __BROKEN_FWRITE
USERINCLUDE .
START BITMAP PicoDrive.mbm
HEADER
TARGETPATH \Resource\Apps
SOURCEPATH Rsc
SOURCE c24 Pico18x18.bmp
SOURCE 8 Pico18x18m.bmp
SOURCE c24 Pico40x40.bmp
SOURCE 8 Pico40x40m.bmp
SOURCE c24 Pico64x64.bmp
SOURCE 8 Pico64x64m.bmp
END

View file

@ -1,110 +0,0 @@
1. Keys:
If it looks confusing to you, check this tutorial first:
http://notaz.atspace.com/pico_tut/
There are no default settings.
When you start key configuration mode, black screen with dark-red squares will
appear. Also there will be little 'control' on the top with the function
name in it, and arrows on the corners of it. You can tap on these corners to
select a function. You can also tap on these squares to bind that function to
them. This way you can associate touchpad areas with game-controls or functions.
I also made a small square in every corner of the screen to be used as a virtual
button for some function, like save state. You can bind it as you like. To
bind phone buttons, simply select the function you need, and press a button
you want. To unbind any key or touchpad area, simply push or tap it again.
When finished, select 'done' and press any key. You can also press 'Power'
to exit.
You need to bind 'pause emu' function to be able exit game when ROM is loaded.
It is bound to 'back' button by default.
2. Main Settings:
Here you can set the orientation of screen and the drawing mode. The "fit"
option will scale the image so it better fits in the screen, but some detail
will be lost. "center" displays the game at the center of the screen, but
non-fitting parts are not visible then. "fit2" is simmilar to "fit" but is
a bit more stretched (fit modes are only meaningful in 0 or 180 rotation
modes).
"Fast renderer" enables faster rendering method, but it works only with some
games (some other have serious glitches or even hang).
"Accurate timing" is needed for some games to run (like Red Zone). It should
be kept off for all other games, because it slows emulation down. Some games
also need this option for proper sound, so enable this if game has any
glitches.
"Accurate sprites" fixes sprite priority problems, for example if game
character is in front of or behind some object it should not be, this option
should fix it. This option does not work in "Fast renderer" mode.
"Show FPS" shows game frames per second in format XX/YY, where XX is the
number of frames shown per previous second, and YY is the number of frames
emulated, but not necessarily shown. By calculating YY-XX you get the number
of skipped frames per second.
3. Sound settings:
Sound emulation is very picky on CPU power (in most cases sound alone uses
more CPU power than everything else altogether), but it is still possible to
play some games. When using sound, the recommended display modes are "fit 0"
and "fit 180", because these are the fastest ones. Also try "Alternative
renderer", but it might cause graphical glitches. You must use auto frameskip
when using sound, or else you will get stuttering sound. Also, it is
recommended to exit all other non-vital apps (you can use SMan for this),
disable bluetooth and any other devices your phone may have. I also noticed
that simply connecting the phone battery charger strangely slows everything
down.
"Enable sound" tries to enable sound output on your device, but that alone is
not enough to get sound. You need to enable the sound chips below:
"Z80" is secondary CPU in genesis and is mostly used to control the other 2
sound chips. So if you disable Z80, sound will be lost in most games, with
some exceptions like Sonic1. It is possible to use Z80 for other things,
some games do that and Z80 must be enabled to run them at all.
"YM2612" is a fairly complex Frequency Modulation (FM) sound synthesis chip.
It was the main sound output device in genesis and is horrible CPU hog when
is tried to be emulated in software. Disabling it gives large speed
improvement, but most of the sound is lost.
"SN76496" is programmable sound generator (PSG) chip, used for various sound
effects and music elements.
Note: if you change sound settings AFTER loading a ROM, you may need to reset
game to get sound. This is because most games initialize sound chips on
startup, and this data is lost when sound chips are being enabled/disabled.
4. Misc:
"6 button pad" will enable 6 button gamepad emulation and will add additional
X, Y, Z and MODE actions to key configuration.
Note: if you enable this, games may detect that and use different button
configuration, for example A ("high punch") will change to "low punch" in
Mortal Kombat and you will need to bind X for "high punch".
"gzip save states" enables gzip (similar to ordinary zip, but a little
different) compression on your save states to save space. The compression
ratio is 50-90%, so it's worth to enable this.
"Use SRAM saves" option enables emulation of batery-backed save RAM some game
cartridges had. RPG games used it alot, but there were some others too, like
Sonic 3. If this is enabled, <ROMname>.srm files are generated when you exit
the emulator or load another ROM. Format is compatible with other popular
emulators (like Gens and Fusion).
"Region" lets you set the region of emulated genesis machine.
5. Frameskip:
"Auto" option tries to run the game in it's original speed by skipping next
frame if the previous was rendered too slow.
"0" displays every frame, thus game runs very slow, sound skips.
"1" skips every other frame. Use this for a game which is smoother, but a bit
too slow (actually depends on display mode you use).
"2" also makes the game smoother, but it will be too fast in most areas.
"4","8" similar to above, but skips more frames and often becomes choppy.

View file

@ -1,157 +0,0 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "../common/emu.h"
#include "../common/config.h"
#include "../common/menu.h"
#include "pico/pico_int.h"
const char * const keyNames[] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
int plat_get_root_dir(char *dst, int len)
{
strcpy(dst, "D:\\other\\PicoDrive\\");
return strlen(dst);
}
void emu_Init(void)
{
int ret;
// make dirs for saves, cfgs, etc.
ret = mkdir("D:\\other\\PicoDrive", 0777);
if (ret == 0)
{
mkdir("D:\\other\\PicoDrive\\mds", 0777);
mkdir("D:\\other\\PicoDrive\\srm", 0777);
mkdir("D:\\other\\PicoDrive\\brm", 0777);
}
emu_prepareDefaultConfig();
config_readlrom("D:\\other\\PicoDrive\\config.cfg");
emu_read_config(0, 0);
//PicoInit();
}
void emu_Deinit(void)
{
// saves volume and last ROM
emu_WriteConfig(0);
//PicoExit();
}
void menu_romload_prepare(const char *rom_name)
{
}
void menu_romload_end(void)
{
}
void emu_prepareDefaultConfig(void)
{
memset(&defaultConfig, 0, sizeof(defaultConfig));
defaultConfig.EmuOpt = 0x1d | 0x680; // | confirm_save, cd_leds, 16bit rend
defaultConfig.s_PicoOpt = 0x0f | POPT_EN_MCD_PCM|POPT_EN_MCD_CDDA|POPT_EN_SVP_DRC|POPT_ACC_SPRITES;
defaultConfig.s_PsndRate = 22050;
defaultConfig.s_PicoRegion = 0; // auto
defaultConfig.s_PicoAutoRgnOrder = 0x184; // US, EU, JP
defaultConfig.s_PicoCDBuffers = 0;
defaultConfig.Frameskip = -1; // auto
defaultConfig.volume = 80;
defaultConfig.scaling = 0;
defaultConfig.KeyBinds[0xd5] = 1<<26; // back
}
void emu_pack_config(void)
{
currentConfig.s_PicoOpt = PicoOpt;
currentConfig.s_PsndRate = PsndRate;
currentConfig.s_PicoRegion = PicoRegionOverride;
currentConfig.s_PicoAutoRgnOrder = PicoAutoRgnOrder;
currentConfig.s_PicoCDBuffers = PicoCDBuffers;
}
void emu_unpack_config(void)
{
PicoOpt = currentConfig.s_PicoOpt;
PsndRate = currentConfig.s_PsndRate;
PicoRegionOverride = currentConfig.s_PicoRegion;
PicoAutoRgnOrder = currentConfig.s_PicoAutoRgnOrder;
PicoCDBuffers = currentConfig.s_PicoCDBuffers;
}
/* used by config engine only, not actual menus */
menu_entry opt_entries[] =
{
{ NULL, MB_NONE, MA_OPT_RENDERER, NULL, 0, 0, 0, 1, 1 },
{ "Scaling", MB_RANGE, MA_OPT_SCALING, &currentConfig.scaling, 0, 0, 2, 1, 1 },
{ "Rotation", MB_RANGE, MA_OPT_ROTATION, &currentConfig.rotation, 0, 0, 3, 1, 1 },
{ "Accurate sprites", MB_ONOFF, MA_OPT_ACC_SPRITES, &PicoOpt, 0x080, 0, 0, 0, 1 },
{ "Show FPS", MB_ONOFF, MA_OPT_SHOW_FPS, &currentConfig.EmuOpt, 0x002, 0, 0, 1, 1 },
{ NULL, MB_RANGE, MA_OPT_FRAMESKIP, &currentConfig.Frameskip, 0, -1, 16, 1, 1 },
{ "Enable sound", MB_ONOFF, MA_OPT_ENABLE_SOUND, &currentConfig.EmuOpt, 0x004, 0, 0, 1, 1 },
{ NULL, MB_NONE, MA_OPT_SOUND_QUALITY, NULL, 0, 0, 0, 1, 1 },
{ NULL, MB_NONE, MA_OPT_REGION, NULL, 0, 0, 0, 1, 1 },
{ "Use SRAM/BRAM savestates", MB_ONOFF, MA_OPT_SRAM_STATES, &currentConfig.EmuOpt, 0x001, 0, 0, 1, 1 },
};
#define OPT_ENTRY_COUNT (sizeof(opt_entries) / sizeof(opt_entries[0]))
const int opt_entry_count = OPT_ENTRY_COUNT;
menu_entry opt2_entries[] =
{
{ "Disable sprite limit", MB_ONOFF, MA_OPT2_NO_SPRITE_LIM, &PicoOpt, 0x40000, 0, 0, 1, 1 },
{ "Emulate Z80", MB_ONOFF, MA_OPT2_ENABLE_Z80, &PicoOpt, 0x00004, 0, 0, 1, 1 },
{ "Emulate YM2612 (FM)", MB_ONOFF, MA_OPT2_ENABLE_YM2612, &PicoOpt, 0x00001, 0, 0, 1, 1 },
{ "Emulate SN76496 (PSG)", MB_ONOFF, MA_OPT2_ENABLE_SN76496,&PicoOpt, 0x00002, 0, 0, 1, 1 },
{ "gzip savestates", MB_ONOFF, MA_OPT2_GZIP_STATES, &currentConfig.EmuOpt, 0x0008, 0, 0, 1, 1 },
{ "SVP dynarec", MB_ONOFF, MA_OPT2_SVP_DYNAREC, &PicoOpt, 0x20000, 0, 0, 1, 1 },
{ "Disable idle loop patching",MB_ONOFF, MA_OPT2_NO_IDLE_LOOPS, &PicoOpt, 0x80000, 0, 0, 1, 1 },
};
#define OPT2_ENTRY_COUNT (sizeof(opt2_entries) / sizeof(opt2_entries[0]))
const int opt2_entry_count = OPT2_ENTRY_COUNT;
menu_entry cdopt_entries[] =
{
{ "CD LEDs", MB_ONOFF, MA_CDOPT_LEDS, &currentConfig.EmuOpt, 0x0400, 0, 0, 1, 1 },
{ "CDDA audio", MB_ONOFF, MA_CDOPT_CDDA, &PicoOpt, 0x0800, 0, 0, 1, 1 },
{ "PCM audio", MB_ONOFF, MA_CDOPT_PCM, &PicoOpt, 0x0400, 0, 0, 1, 1 },
{ NULL, MB_NONE, MA_CDOPT_READAHEAD, NULL, 0, 0, 0, 1, 1 },
{ "SaveRAM cart", MB_ONOFF, MA_CDOPT_SAVERAM, &PicoOpt, 0x8000, 0, 0, 1, 1 },
{ "Scale/Rot. fx (slow)", MB_ONOFF, MA_CDOPT_SCALEROT_CHIP,&PicoOpt, 0x1000, 0, 0, 1, 1 },
{ "Better sync (slow)", MB_ONOFF, MA_CDOPT_BETTER_SYNC, &PicoOpt, 0x2000, 0, 0, 1, 1 },
};
#define CDOPT_ENTRY_COUNT (sizeof(cdopt_entries) / sizeof(cdopt_entries[0]))
const int cdopt_entry_count = CDOPT_ENTRY_COUNT;
menu_entry ctrlopt_entries[] =
{
{ "6 button pad", MB_ONOFF, MA_OPT_6BUTTON_PAD, &PicoOpt, 0x020, 0, 0, 1, 1 },
{ "Turbo rate", MB_RANGE, MA_CTRL_TURBO_RATE, &currentConfig.turbo_rate, 0, 1, 30, 1, 1 },
};
#define CTRLOPT_ENTRY_COUNT (sizeof(ctrlopt_entries) / sizeof(ctrlopt_entries[0]))
const int ctrlopt_entry_count = CTRLOPT_ENTRY_COUNT;
me_bind_action emuctrl_actions[] =
{
{ "Load State ", 1<<28 },
{ "Save State ", 1<<27 },
{ "Pause Emu ", 1<<26 },
{ "Switch Renderer", 1<<25 },
{ "Prev save slot ", 1<<23 },
{ "Next save slot ", 1<<22 },
{ "Volume down ", 1<<21 },
{ "Volume up ", 1<<20 },
{ NULL, 0 }
};

View file

@ -1,32 +0,0 @@
/*******************************************************************
*
* File: PolledAS.h
*
* Author: Peter van Sebille (peter@yipton.net)
*
* (c) Copyright 2001, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#ifndef __POLLED_AS_H
#define __POLLED_AS_H
class CPrivatePolledActiveScheduler;
class CPolledActiveScheduler : public CBase
{
public:
~CPolledActiveScheduler();
static CPolledActiveScheduler* NewL();
static CPolledActiveScheduler* Instance();
void Schedule();
protected:
CPolledActiveScheduler(){};
void ConstructL();
CPrivatePolledActiveScheduler* iPrivatePolledActiveScheduler;
};
#endif /* __POLLED_AS_H */

View file

@ -1,317 +0,0 @@
/*******************************************************************
*
* File: Audio_mediaserver.cpp
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2001, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#include "audio_mediaserver.h"
#include "debug.h"
//#define DEBUG_UNDERFLOWS
//#undef DEBUGPRINT
//#define DEBUGPRINT(x...)
const TInt KUpdatesPerSec = 10;
const TInt KBlockTime = 1000000 / KUpdatesPerSec;
const TInt KMaxLag = 200000; // max sound lag, lower values increase chance of underflow
const TInt KMaxUnderflows = 50; // max underflows/API errors we are going allow in a row (to prevent lockups)
/*******************************************
*
* CGameAudioMS
*
*******************************************/
CGameAudioMS::CGameAudioMS(TInt aRate, TBool aStereo, TInt aWritesPerSec, TInt aVolume)
: iRate(aRate), iStereo(aStereo), iWritesPerSec(aWritesPerSec), iVolume(aVolume)
{
}
CGameAudioMS* CGameAudioMS::NewL(TInt aRate, TBool aStereo, TInt aWritesPerSec, TInt aVolume)
{
DEBUGPRINT(_L("CGameAudioMS::NewL(%i, %i, %i, %i)"), aRate, aStereo, aWritesPerSec, aVolume);
CGameAudioMS* self = new(ELeave) CGameAudioMS(aRate, aStereo, aWritesPerSec, aVolume);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(); // self
return self;
}
CGameAudioMS::~CGameAudioMS()
{
DEBUGPRINT(_L("CGameAudioMS::~CGameAudioMS()"));
if(iMdaAudioOutputStream) {
iScheduler->Schedule(); // let it finish it's stuff
iMdaAudioOutputStream->Stop();
delete iMdaAudioOutputStream;
}
if(iServer) delete iServer;
for (TInt i=0; i<KSoundBuffers; i++)
delete iSoundBuffers[i];
// Polled AS
//if(iScheduler) delete iScheduler;
}
void CGameAudioMS::ConstructL()
{
iServer = CMdaServer::NewL();
// iScheduler = CPolledActiveScheduler::NewL();
iScheduler = CPolledActiveScheduler::Instance();
switch(iRate) {
case 11025: iMdaAudioDataSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate11025Hz; break;
case 16000: iMdaAudioDataSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate16000Hz; break;
case 22050: iMdaAudioDataSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate22050Hz; break;
case 44100: iMdaAudioDataSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate44100Hz; break;
default: iMdaAudioDataSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate8000Hz; break;
}
iMdaAudioDataSettings.iChannels = (iStereo) ? TMdaAudioDataSettings::EChannelsStereo : TMdaAudioDataSettings::EChannelsMono;
iMdaAudioDataSettings.iCaps = TMdaAudioDataSettings::ESampleRateFixed | iMdaAudioDataSettings.iSampleRate;
iMdaAudioDataSettings.iFlags = TMdaAudioDataSettings::ENoNetworkRouting;
iMaxWriteSamples = iRate / iWritesPerSec;
if (iRate % iWritesPerSec)
iMaxWriteSamples++;
int bufferedFrames = iWritesPerSec / KUpdatesPerSec;
iBufferSize = iMaxWriteSamples * (iStereo ? 4 : 2);
iBufferSize *= bufferedFrames;
for (TInt i=0 ; i<KSoundBuffers ; i++)
{
// it seems .SetLength(max) throws USER:23 panic,
// so make them a bit larger
iSoundBuffers[i] = HBufC8::NewL(iBufferSize+4);
iSoundBuffers[i]->Des().FillZ (iBufferSize+4);
}
iCurrentBuffer = 0;
iCurrentBufferSize = 0;
DEBUGPRINT(_L("sound: iMaxWriteSamples: %i, iBufferSize: %i"), iMaxWriteSamples, iBufferSize);
// here we actually test if we can create and open CMdaAudioOutputStream at all, but really create and use it later.
iMdaAudioOutputStream = CMdaAudioOutputStream::NewL(iListener, iServer);
if (iMdaAudioOutputStream) {
if (iVolume < 0 || iVolume > iMdaAudioOutputStream->MaxVolume())
iVolume = iMdaAudioOutputStream->MaxVolume();
delete iMdaAudioOutputStream;
iMdaAudioOutputStream = 0;
}
}
// returns a pointer to buffer for next frame,
// to be used when iSoundBuffers are used directly
TInt16 *CGameAudioMS::NextFrameL(TInt aPcmFrames)
{
TInt mul = iStereo ? 4 : 2;
TInt bytes = aPcmFrames * mul;
iCurrentPosition += bytes / 2;
iCurrentBufferSize += bytes;
if (aPcmFrames > iMaxWriteSamples) {
DEBUGPRINT(_L("too many samples: %i > %i"), aPcmFrames, iMaxWriteSamples);
}
if (iCurrentBufferSize + iMaxWriteSamples * mul > iBufferSize)
{
//DEBUGPRINT(_L("write on iCurrentBufferSize %i"), iCurrentBufferSize);
WriteBlockL();
}
iScheduler->Schedule();
if(iListener.iUnderflowed) {
if(iListener.iUnderflowed > KMaxUnderflows) {
delete iMdaAudioOutputStream;
iMdaAudioOutputStream = 0;
return 0;
}
UnderflowedL(); // not again!
}
return iCurrentPosition;
}
void CGameAudioMS::WriteBlockL()
{
iScheduler->Schedule();
// do not write until stream is open
if(!iListener.iIsOpen) WaitForOpenToCompleteL();
//if(!iListener.iHasCopied) WaitForCopyToCompleteL(); // almost never happens anyway and sometimes even deadlocks?
//iListener.iHasCopied = EFalse;
if(!iListener.iUnderflowed) {
TInt64 delta;
// don't write if sound is lagging too much
delta = iTime - iMdaAudioOutputStream->Position().Int64();
if (delta > MAKE_TINT64(0, KMaxLag))
// another query sometimes returns very different result
delta = iTime - iMdaAudioOutputStream->Position().Int64();
if(delta <= MAKE_TINT64(0, KMaxLag)) {
//RDebug::Print(_L("delta: %i"), iTime.Low() - iMdaAudioOutputStream->Position().Int64().Low());
iSoundBuffers[iCurrentBuffer]->Des().SetLength(iCurrentBufferSize);
iMdaAudioOutputStream->WriteL(*iSoundBuffers[iCurrentBuffer]);
iTime += KBlockTime;
} else {
DEBUGPRINT(_L("lag: %i"), I64LOW(delta));
}
}
if (++iCurrentBuffer == KSoundBuffers)
iCurrentBuffer = 0;
iSoundBuffers[iCurrentBuffer]->Des().SetMax();
iCurrentPosition = (TInt16*) iSoundBuffers[iCurrentBuffer]->Ptr();
iCurrentBufferSize = 0;
}
void CGameAudioMS::Pause()
{
if(!iMdaAudioOutputStream) return;
iScheduler->Schedule(); // let it finish it's stuff
iMdaAudioOutputStream->Stop();
delete iMdaAudioOutputStream;
iMdaAudioOutputStream = 0;
}
// call this before doing any playback!
TInt16 *CGameAudioMS::ResumeL()
{
DEBUGPRINT(_L("CGameAudioMS::Resume()"));
iScheduler->Schedule();
// we act a bit strange here: simulate buffer underflow, which actually starts audio
iListener.iIsOpen = ETrue;
iListener.iUnderflowed = 1;
iListener.iLastError = 0;
iCurrentBufferSize = 0;
iCurrentPosition = (TInt16*) iSoundBuffers[iCurrentBuffer]->Ptr();
return iCurrentPosition;
}
// handles underflow condition
void CGameAudioMS::UnderflowedL()
{
#ifdef DEBUG_UNDERFLOWS
DEBUGPRINT(_L("UnderflowedL()"));
#endif
if (iListener.iLastError != KErrUnderflow)
{
// recreate the stream
//iMdaAudioOutputStream->Stop();
if(iMdaAudioOutputStream) delete iMdaAudioOutputStream;
iMdaAudioOutputStream = CMdaAudioOutputStream::NewL(iListener, iServer);
iMdaAudioOutputStream->Open(&iMdaAudioDataSettings);
iMdaAudioOutputStream->SetAudioPropertiesL(iMdaAudioDataSettings.iSampleRate, iMdaAudioDataSettings.iChannels);
iMdaAudioOutputStream->SetVolume(iVolume); // new in UIQ3
iListener.iIsOpen = EFalse; // wait for it to open
//iListener.iHasCopied = ETrue; // but don't wait for last copy to complete
// let it open and feed some stuff to make it happy
User::After(0);
iScheduler->Schedule();
iListener.iLastError = 0;
if(!iListener.iIsOpen) WaitForOpenToCompleteL();
} else {
iListener.iLastError = iListener.iUnderflowed = 0;
}
iTime = iMdaAudioOutputStream->Position().Int64();
}
void CGameAudioMS::WaitForOpenToCompleteL()
{
DEBUGPRINT(_L("CGameAudioMS::WaitForOpenToCompleteL"));
TInt count = 20; // 2 seconds
TInt waitPeriod = 100 * 1000;
if(!iListener.iIsOpen) {
// it is often enough to do this
User::After(0);
iScheduler->Schedule();
}
while (!iListener.iIsOpen && --count)
{
User::After(waitPeriod);
iScheduler->Schedule();
}
if (!iListener.iIsOpen)
User::LeaveIfError(KErrNotSupported);
}
TInt CGameAudioMS::ChangeVolume(TInt aUp)
{
//DEBUGPRINT(_L("CGameAudioMS::ChangeVolume(%i)"), aUp);
if (iMdaAudioOutputStream) {
if (aUp) {
iVolume += 5;
if (iVolume > iMdaAudioOutputStream->MaxVolume())
iVolume = iMdaAudioOutputStream->MaxVolume();
} else {
iVolume -= 5;
if (iVolume < 0) iVolume = 0;
}
iMdaAudioOutputStream->SetVolume(iVolume);
}
return iVolume;
}
void TGameAudioEventListener::MaoscOpenComplete(TInt aError)
{
#ifdef DEBUG_UNDERFLOWS
DEBUGPRINT(_L("CGameAudioMS::MaoscOpenComplete, error=%d"), aError);
#endif
iIsOpen = ETrue;
if(aError) {
iLastError = aError;
iUnderflowed++;
}
else iUnderflowed = 0;
}
void TGameAudioEventListener::MaoscBufferCopied(TInt aError, const TDesC8& aBuffer)
{
if (aError)
DEBUGPRINT(_L("CGameAudioMS::MaoscBufferCopied, error=%d"), aError);
// iHasCopied = ETrue;
if(aError) { // shit!
iLastError = aError;
iUnderflowed++;
}
}
void TGameAudioEventListener::MaoscPlayComplete(TInt aError)
{
#ifdef DEBUG_UNDERFLOWS
DEBUGPRINT(_L("CGameAudioMS::MaoscPlayComplete: %i"), aError);
#endif
if(aError) {
iLastError = aError;
iUnderflowed++; // never happened to me while testing, but just in case
}
}

View file

@ -1,85 +0,0 @@
/*******************************************************************
*
* File: Audio_mediaserver.h
*
* Author: Peter van Sebille (peter@yipton.net)
*
* Modified/adapted for picodriveN by notaz, 2006
*
* (c) Copyright 2006, notaz
* (c) Copyright 2001, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
#ifndef __AUDIO_MEDIASERVER_H
#define __AUDIO_MEDIASERVER_H
#include <mda/common/audio.h>
#include <mdaaudiooutputstream.h>
//#include "audio.h"
#include "PolledAS.h"
const TInt KSoundBuffers = 4;
class TGameAudioEventListener : public MMdaAudioOutputStreamCallback
{
public: // implements MMdaAudioOutputStreamCallback
void MaoscOpenComplete(TInt aError);
void MaoscBufferCopied(TInt aError, const TDesC8& );
void MaoscPlayComplete(TInt aError);
TBool iIsOpen;
// TBool iHasCopied;
TInt iUnderflowed;
TInt iLastError;
};
class CGameAudioMS // : public IGameAudio // IGameAudio MUST be specified first!
{
public: // implements IGameAudio
TInt16 *NextFrameL(TInt aPcmFrames);
TInt16 *ResumeL();
void Pause();
TInt ChangeVolume(TInt aUp);
public:
~CGameAudioMS();
CGameAudioMS(TInt aRate, TBool aStereo, TInt aWritesPerSec, TInt aVolume);
static CGameAudioMS* NewL(TInt aRate, TBool aStereo, TInt aWritesPerSec, TInt aVolume);
protected:
void WriteBlockL();
void UnderflowedL();
void ConstructL();
protected:
void WaitForOpenToCompleteL();
TInt iRate;
TBool iStereo;
CMdaAudioOutputStream *iMdaAudioOutputStream;
TMdaAudioDataSettings iMdaAudioDataSettings;
TGameAudioEventListener iListener;
CPolledActiveScheduler *iScheduler;
HBufC8* iSoundBuffers[KSoundBuffers];
TInt iWritesPerSec; // fps, may be more actual writes
TInt iMaxWriteSamples; // max samples per write
TInt16* iCurrentPosition;
TInt iCurrentBuffer; // active buffer
TInt iCurrentBufferSize; // bytes filled in buffer
TInt iBufferSize;
CMdaServer* iServer;
TInt64 iTime;
TInt iVolume;
};
#endif /* __AUDIO_MEDIASERVER_H */

View file

@ -1,34 +0,0 @@
/*
void vidConvCpyRGB32 (void *to, void *from, int lines, int p240)
{
unsigned short *ps = (unsigned short *) from;
unsigned long *pd = (unsigned long *) to;
int x, y;
int to_x = p240 ? 240 : 224;
if(!p240) pd += 8;
for(y = 0; y < lines; y++) // ps < ps_end; ps++)
for(x = 0; x < to_x; x++, ps++)
// Convert 0000bbb0 ggg0rrr0
// to ..0 rrr00000 ggg00000 bbb00000
*(pd+y*256+x) = ((*ps&0x000F)<<20) | ((*ps&0x00F0)<<8) | ((*ps&0x0F00)>>4);
}
*/
// stubs
void vidConvCpyRGB32 (void *to, void *from, int pixels) {}
void vidConvCpyRGB32sh(void *to, void *from, int pixels) {}
void vidConvCpyRGB32hi(void *to, void *from, int pixels) {}
void vidConvCpy_90 (void *to, void *from, void *pal, int width) {}
void vidConvCpy_270 (void *to, void *from, void *pal, int width) {}
void vidConvCpy_center_0 (void *to, void *from, void *pal) {}
void vidConvCpy_center_180(void *to, void *from, void *pal) {}
void vidConvCpy_center2_40c_0 (void *to, void *from, void *pal, int lines) {}
void vidConvCpy_center2_40c_180(void *to, void *from, void *pal, int lines) {}
void vidConvCpy_center2_32c_0 (void *to, void *from, void *pal, int lines) {}
void vidConvCpy_center2_32c_180(void *to, void *from, void *pal, int lines) {}
void vidClear(void *to, int lines) {}

View file

@ -1,22 +0,0 @@
// (c) Copyright 2006 notaz, All rights reserved.
// Free for non-commercial use.
// For commercial use, separate licencing terms must be obtained.
extern "C"
{
void vidConvCpyRGB32 (void *to, void *from, int pixels);
void vidConvCpyRGB32sh(void *to, void *from, int pixels);
void vidConvCpyRGB32hi(void *to, void *from, int pixels);
void vidConvCpy_90 (void *to, void *from, void *pal, int width);
void vidConvCpy_270 (void *to, void *from, void *pal, int width);
void vidConvCpy_center_0 (void *to, void *from, void *pal);
void vidConvCpy_center_180(void *to, void *from, void *pal);
void vidConvCpy_center2_40c_0 (void *to, void *from, void *pal, int lines);
void vidConvCpy_center2_40c_180(void *to, void *from, void *pal, int lines);
void vidConvCpy_center2_32c_0 (void *to, void *from, void *pal, int lines);
void vidConvCpy_center2_32c_180(void *to, void *from, void *pal, int lines);
void vidClear(void *to, int lines);
}

View file

@ -1,724 +0,0 @@
@ vim:filetype=armasm
@ some color conversion and blitting routines
@ (c) Copyright 2006, notaz
@ All Rights Reserved
.include "port_config.s"
@ Convert 0000bbb0 ggg0rrr0 0000bbb0 ggg0rrr0
@ to 00000000 rrr00000 ggg00000 bbb00000 ...
@ lr = 0x00e000e0, out: r3=lower_pix, r2=higher_pix; trashes rin
@ if sh==2, r8=0x00404040 (sh!=0 destroys flags!)
.macro convRGB32_2 rin sh=0
and r2, lr, \rin, lsr #4 @ blue
and r3, \rin, lr
orr r2, r2, r3, lsl #8 @ g0b0g0b0
mov r3, r2, lsl #16 @ g0b00000
and \rin,lr, \rin, ror #12 @ 00r000r0 (reversed)
orr r3, r3, \rin, lsr #16 @ g0b000r0
.if \sh == 1
mov r3, r3, ror #17 @ shadow mode
.elseif \sh == 2
adds r3, r3, #0x40000000 @ green
orrcs r3, r3, #0xe0000000
mov r3, r3, ror #8
adds r3, r3, #0x40000000
orrcs r3, r3, #0xe0000000
mov r3, r3, ror #16
adds r3, r3, #0x40000000
orrcs r3, r3, #0xe0000000
mov r3, r3, ror #24
orr r3, r3, r3, lsr #3
.else
mov r3, r3, ror #16 @ r3=low
orr r3, r3, r3, lsr #3
.endif
str r3, [r0], #4
mov r2, r2, lsr #16
orr r2, r2, \rin, lsl #16
.if \sh == 1
mov r2, r2, lsr #1
.elseif \sh == 2
mov r2, r2, ror #8
adds r2, r2, #0x40000000 @ blue
orrcs r2, r2, #0xe0000000
mov r2, r2, ror #8
adds r2, r2, #0x40000000
orrcs r2, r2, #0xe0000000
mov r2, r2, ror #8
adds r2, r2, #0x40000000
orrcs r2, r2, #0xe0000000
mov r2, r2, ror #8
orr r2, r2, r2, lsr #3
.else
orr r2, r2, r2, lsr #3
.endif
str r2, [r0], #4
.endm
.global vidConvCpyRGB32 @ void *to, void *from, int pixels
vidConvCpyRGB32:
stmfd sp!, {r4-r7,lr}
mov r12, r2, lsr #3 @ repeats
mov lr, #0x00e00000
orr lr, lr, #0x00e0
.loopRGB32:
subs r12, r12, #1
ldmia r1!, {r4-r7}
convRGB32_2 r4
convRGB32_2 r5
convRGB32_2 r6
convRGB32_2 r7
bgt .loopRGB32
ldmfd sp!, {r4-r7,lr}
bx lr
.global vidConvCpyRGB32sh @ void *to, void *from, int pixels
vidConvCpyRGB32sh:
stmfd sp!, {r4-r7,lr}
mov r12, r2, lsr #3 @ repeats
mov lr, #0x00e00000
orr lr, lr, #0x00e0
.loopRGB32sh:
subs r12, r12, #1
ldmia r1!, {r4-r7}
convRGB32_2 r4, 1
convRGB32_2 r5, 1
convRGB32_2 r6, 1
convRGB32_2 r7, 1
bgt .loopRGB32sh
ldmfd sp!, {r4-r7,lr}
bx lr
.global vidConvCpyRGB32hi @ void *to, void *from, int pixels
vidConvCpyRGB32hi:
stmfd sp!, {r4-r7,lr}
mov r12, r2, lsr #3 @ repeats
mov lr, #0x00e00000
orr lr, lr, #0x00e0
.loopRGB32hi:
ldmia r1!, {r4-r7}
convRGB32_2 r4, 2
convRGB32_2 r5, 2
convRGB32_2 r6, 2
convRGB32_2 r7, 2
subs r12, r12, #1
bgt .loopRGB32hi
ldmfd sp!, {r4-r7,lr}
bx lr
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ -------- M2 stuff ---------
/*
.global vidConvCpy_90 @ void *to, void *from, int width
vidConvCpy_90:
stmfd sp!, {r4-r10,lr}
mov lr, #0x00F00000
orr lr, lr, #0x00F0
mov r12, #224/4 @ row counter
mov r10, r2, lsl #2 @ we do 2 pixel wide copies
add r8, r0, #256*4 @ parallel line
add r1, r1, #0x23000
add r1, r1, #0x00B80 @ r1+=328*223*2+8*2
mov r9, r1
mov r4, #0 @ fill bottom border
mov r5, #0
mov r6, #0
mov r7, #0
stmia r0!, {r4-r7}
stmia r0!, {r4-r7}
stmia r8!, {r4-r7}
stmia r8!, {r4-r7}
.loopM2RGB32_90:
subs r12, r12, #1
@ at first this loop was written differently: src pixels were fetched with ldm's and
@ dest was not sequential. It ran nearly 2 times slower. It seems it is very important
@ to do sequential memory access on those items, which we have more (to offload addressing bus?).
ldr r4, [r1], #-328*2
ldr r5, [r1], #-328*2
ldr r6, [r1], #-328*2
ldr r7, [r1], #-328*2
convRGB32_2 r4, 1
convRGB32_2 r5, 1
convRGB32_2 r6, 1
convRGB32_2 r7, 1
str r4, [r8], #4
str r5, [r8], #4
str r6, [r8], #4
str r7, [r8], #4
bne .loopM2RGB32_90
mov r4, #0 @ top border
mov r5, #0
mov r6, #0
stmia r0!, {r4-r6,r12}
stmia r0!, {r4-r6,r12}
stmia r8!, {r4-r6,r12}
stmia r8!, {r4-r6,r12}
subs r10, r10, #1
ldmeqfd sp!, {r4-r10,pc} @ return
add r0, r8, #16*4 @ set new dst pointer
add r8, r0, #256*4
add r9, r9, #2*2 @ fix src pointer
mov r1, r9
stmia r0!, {r4-r6,r12} @ bottom border
stmia r0!, {r4-r6,r12}
stmia r8!, {r4-r6,r12}
stmia r8!, {r4-r6,r12}
mov r12, #224/4 @ restore row counter
b .loopM2RGB32_90
@ converter for vidConvCpy_270
@ lr = 0x00F000F0, out: r3=lower_pix, r2=higher_pix; trashes rin
.macro convRGB32_3 rin
and r2, lr, \rin, lsr #4 @ blue
and r3, \rin, lr
orr r2, r2, r3, lsl #8 @ g0b0g0b0
mov r3, r2, lsl #16 @ g0b00000
and \rin,lr, \rin, ror #12 @ 00r000r0 (reversed)
orr r3, r3, \rin, lsr #16 @ g0b000r0
mov r2, r2, lsr #16
orr r2, r2, \rin, lsl #16
str r2, [r0], #4
mov \rin,r3, ror #16 @ r3=low
.endm
*/
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ takes byte-sized pixels from r3-r6, fetches from pal and stores to r7,r8,r10,lr
@ r2=pal
.macro mode2_4pix shift
and r7, r11, r3, lsr #\shift
ldr r7, [r2, r7, lsl #2]
and r8, r11, r4, lsr #\shift
ldr r8, [r2, r8, lsl #2]
and r10,r11, r5, lsr #\shift
ldr r10,[r2, r10,lsl #2]
and lr, r11, r6, lsr #\shift
ldr lr, [r2, lr, lsl #2]
.endm
@ r2=pal, r11=0xff
.macro mode2_4pix_getpix0 dreg sreg
and \dreg, r11, \sreg
ldr \dreg, [r2, \dreg, lsl #2]
.endm
.macro mode2_4pix_getpix1 dreg sreg
and \dreg, r11, \sreg, lsr #8
ldr \dreg, [r2, \dreg, lsl #2]
.endm
.macro mode2_4pix_getpix2 dreg sreg
and \dreg, r11, \sreg, lsr #16
ldr \dreg, [r2, \dreg, lsl #2]
.endm
.macro mode2_4pix_getpix3 dreg sreg
and \dreg, r11, \sreg, lsr #24
ldr \dreg, [r2, \dreg, lsl #2]
.endm
@ takes byte-sized pixels from reg, fetches from pal and stores to r3-r6
@ r11=0xFF, r2=pal
.macro mode2_4pix2_0 reg
mode2_4pix_getpix0 r3, \reg
mode2_4pix_getpix1 r4, \reg
mode2_4pix_getpix2 r5, \reg
mode2_4pix_getpix3 r6, \reg
.endm
@ ...
.macro mode2_4pix2_180 reg
mode2_4pix_getpix3 r3, \reg
mode2_4pix_getpix2 r4, \reg
mode2_4pix_getpix1 r5, \reg
mode2_4pix_getpix0 r6, \reg
.endm
@ takes byte-sized pixels from reg, fetches from pal and stores to r3-r5
@ r11=0xFF, r2=pal, r10=0xfcfcfc, r6=tmp
.macro mode2_4pix_to3 reg is180
.if \is180
mode2_4pix_getpix3 r3, \reg
mode2_4pix_getpix2 r4, \reg
.else
mode2_4pix_getpix0 r3, \reg @ gathering loads cause a weird-hang
mode2_4pix_getpix1 r4, \reg
.endif
sub r3, r3, r3, lsr #2 @ r3 *= 0.75
add r3, r3, r4, lsr #2 @ r3 += r4 * 0.25
and r3, r3, r10
.if \is180
mode2_4pix_getpix1 r5, \reg
mode2_4pix_getpix0 r6, \reg
.else
mode2_4pix_getpix2 r5, \reg
mode2_4pix_getpix3 r6, \reg
.endif
mov r4, r4, lsr #1
add r4, r4, r5, lsr #1 @ r4 = (r4 + r5) / 2;
@ and r4, r4, r10
sub r6, r6, r6, lsr #2 @ r6 *= 0.75
add r5, r6, r5, lsr #2 @ r5 = r6 + r5 * 0.25
and r5, r5, r10
.endm
@ void *to, void *from, void *pal, int width
.macro vidConvCpyM2_landscape is270
stmfd sp!, {r4-r11,lr}
mov r11, #0xff
mov r12, #(224/4-1)<<16 @ row counter
orr r12, r12, r3, lsl #1 @ we do 4 pixel wide copies (right to left)
.if \is270
add r1, r1, #324
.else
add r1, r1, #0x11c00
add r1, r1, #0x00308 @ 328*224+8
.endif
mov r9, r1
mov r3, #0 @ fill top border
mov r4, #0
mov r5, #0
mov r6, #0
stmia r0!, {r3-r6}
stmia r0!, {r3-r6}
add r7, r0, #(240+BORDER_R)*4-8*4
stmia r7!, {r3-r6}
stmia r7!, {r3-r6}
add r7, r7, #(240+BORDER_R)*4-8*4
stmia r7!, {r3-r6}
stmia r7!, {r3-r6}
add r7, r7, #(240+BORDER_R)*4-8*4
stmia r7!, {r3-r6}
stmia r7!, {r3-r6}
0: @ .loopM2RGB32_270:
subs r12, r12, #1<<16
.if \is270
ldr r3, [r1], #328
ldr r4, [r1], #328
ldr r5, [r1], #328
ldr r6, [r1], #328
.else
ldr r3, [r1, #-328]!
ldr r4, [r1, #-328]!
ldr r5, [r1, #-328]!
ldr r6, [r1, #-328]!
.endif
.if \is270
mode2_4pix 24
.else
mode2_4pix 0
.endif
stmia r0, {r7,r8,r10,lr}
add r0, r0, #(240+BORDER_R)*4
.if \is270
mode2_4pix 16
.else
mode2_4pix 8
.endif
stmia r0, {r7,r8,r10,lr}
add r0, r0, #(240+BORDER_R)*4
.if \is270
mode2_4pix 8
.else
mode2_4pix 16
.endif
stmia r0, {r7,r8,r10,lr}
add r0, r0, #(240+BORDER_R)*4
.if \is270
mode2_4pix 0
.else
mode2_4pix 24
.endif
stmia r0!,{r7,r8,r10,lr}
sub r0, r0, #(240+BORDER_R)*4*3
bpl 0b @ .loopM2RGB32_270
mov r3, #0 @ bottom border
mov r4, #0
mov r5, #0
mov r6, #0
stmia r0!, {r3-r6}
stmia r0!, {r3-r6}
add r0, r0, #(240+BORDER_R)*4-8*4
stmia r0!, {r3-r6}
stmia r0!, {r3-r6}
add r0, r0, #(240+BORDER_R)*4-8*4
stmia r0!, {r3-r6}
stmia r0!, {r3-r6}
add r0, r0, #(240+BORDER_R)*4-8*4
stmia r0!, {r3-r6}
nop @ phone crashes if this is commented out. Do I stress it too much?
stmia r0!, {r3-r6}
add r12, r12, #1<<16
subs r12, r12, #1
ldmeqfd sp!, {r4-r11,pc} @ return
.if BORDER_R
add r0, r0, #BORDER_R*4
.endif
.if \is270
sub r9, r9, #4 @ fix src pointer
.else
add r9, r9, #4
.endif
mov r1, r9
stmia r0!, {r3-r6} @ top border
stmia r0!, {r3-r6}
add r7, r0, #(240+BORDER_R)*4-8*4
stmia r7!, {r3-r6}
stmia r7!, {r3-r6}
add r7, r7, #(240+BORDER_R)*4-8*4
stmia r7!, {r3-r6}
stmia r7!, {r3-r6}
add r7, r7, #(240+BORDER_R)*4-8*4
stmia r7!, {r3-r6}
stmia r7!, {r3-r6}
orr r12, r12, #(224/4-1)<<16 @ restore row counter
b 0b @ .loopM2RGB32_270
.endm
.global vidConvCpy_90 @ void *to, void *from, void *pal, int width
vidConvCpy_90:
vidConvCpyM2_landscape 0
.global vidConvCpy_270 @ void *to, void *from, void *pal, int width
vidConvCpy_270:
vidConvCpyM2_landscape 1
.global vidConvCpy_center_0 @ void *to, void *from, void *pal
vidConvCpy_center_0:
stmfd sp!, {r4-r6,r11,lr}
mov r11, #0xff
add r1, r1, #8 @ not border (centering 32col here)
mov r12, #(240/4-1)<<16
orr r12, r12, #224
.loopRGB32_c0:
ldr lr, [r1], #4
subs r12, r12, #1<<16
mode2_4pix2_0 lr
stmia r0!, {r3-r6}
bpl .loopRGB32_c0
sub r12, r12, #1
adds r12, r12, #1<<16
ldmeqfd sp!, {r4-r6,r11,pc} @ return
.if BORDER_R
add r0, r0, #BORDER_R*4
.endif
add r1, r1, #88
orr r12, #(240/4-1)<<16
b .loopRGB32_c0
.global vidConvCpy_center_180 @ void *to, void *from, void *pal
vidConvCpy_center_180:
stmfd sp!, {r4-r6,r11,lr}
mov r11, #0xff
add r1, r1, #0x11c00
add r1, r1, #0x002B8 @ #328*224-72
mov r12, #(240/4-1)<<16
orr r12, r12, #224
.loopRGB32_c180:
ldr lr, [r1, #-4]!
subs r12, r12, #1<<16
mode2_4pix2_180 lr
stmia r0!, {r3-r6}
bpl .loopRGB32_c180
sub r12, r12, #1
adds r12, r12, #1<<16
ldmeqfd sp!, {r4-r6,r11,pc} @ return
.if BORDER_R
add r0, r0, #BORDER_R*4
.endif
sub r1, r1, #88
orr r12, #(240/4-1)<<16
b .loopRGB32_c180
@ note: the following code assumes that (pal[x] & 0x030303) == 0
.global vidConvCpy_center2_40c_0 @ void *to, void *from, void *pal, int lines
vidConvCpy_center2_40c_0:
stmfd sp!, {r4-r6,r10,r11,lr}
mov r11, #0xff
mov r10, #0xfc
orr r10, r10, lsl #8
orr r10, r10, lsl #8
add r1, r1, #8 @ border
mov r12, #(240/3-1)<<16
orr r12, r12, r3
.loopRGB32_c2_40c_0:
ldr lr, [r1], #4
subs r12, r12, #1<<16
mode2_4pix_to3 lr, 0
stmia r0!, {r3-r5}
bpl .loopRGB32_c2_40c_0
sub r12, r12, #1
adds r12, r12, #1<<16
ldmeqfd sp!, {r4-r6,r10,r11,pc} @ return
.if BORDER_R
add r0, r0, #BORDER_R*4
.endif
add r1, r1, #8
orr r12, #(240/3-1)<<16
b .loopRGB32_c2_40c_0
.global vidConvCpy_center2_40c_180 @ void *to, void *from, void *pal, int lines
vidConvCpy_center2_40c_180:
stmfd sp!, {r4-r6,r10,r11,lr}
mov r11, #0xff
mov r10, #0xfc
orr r10, r10, lsl #8
orr r10, r10, lsl #8
mov r4, #328
mla r1, r3, r4, r1
@ add r1, r1, #0x11000
@ add r1, r1, #0x00f00 @ #328*224
mov r12, #(240/3-1)<<16
orr r12, r12, r3
.loop_c2_40c_180:
ldr lr, [r1, #-4]!
subs r12, r12, #1<<16
mode2_4pix_to3 lr, 1
stmia r0!, {r3-r5}
bpl .loop_c2_40c_180
sub r12, r12, #1
adds r12, r12, #1<<16
ldmeqfd sp!, {r4-r6,r10,r11,pc} @ return
.if BORDER_R
add r0, r0, #BORDER_R*4
.endif
sub r1, r1, #8
orr r12, #(240/3-1)<<16
b .loop_c2_40c_180
.global vidConvCpy_center2_32c_0 @ void *to, void *from, void *pal, int lines
vidConvCpy_center2_32c_0:
stmfd sp!, {r4-r11,lr}
mov r10, #0xfc
orr r10, r10, lsl #8
orr r10, r10, lsl #8
mov r11, #0xff
add r1, r1, #8 @ border
mov r12, #(240/15-1)<<16
orr r12, r12, r3
.loop_c2_32c_0:
ldmia r1!, {r7-r9,lr}
subs r12, r12, #1<<16
mode2_4pix2_0 r7
stmia r0!, {r3-r6}
mode2_4pix2_0 r8
stmia r0!, {r3-r6}
mode2_4pix2_0 r9
stmia r0!, {r3-r6}
mode2_4pix_to3 lr, 0
stmia r0!, {r3-r5}
bpl .loop_c2_32c_0
sub r12, r12, #1
adds r12, r12, #1<<16
ldmeqfd sp!, {r4-r11,pc} @ return
.if BORDER_R
add r0, r0, #BORDER_R*4
.endif
add r1, r1, #64+8
orr r12, #(240/15-1)<<16
b .loop_c2_32c_0
.global vidConvCpy_center2_32c_180 @ void *to, void *from, void *pal, int lines
vidConvCpy_center2_32c_180:
stmfd sp!, {r4-r11,lr}
mov r10, #0xfc
orr r10, r10, lsl #8
orr r10, r10, lsl #8
mov r11, #0xff
mov r4, #328
mla r1, r3, r4, r1
@ add r1, r1, #0x11000
@ add r1, r1, #0x00f00 @ #328*224
mov r12, #(240/15-1)<<16
orr r12, r12, r3
.loop_c2_32c_180:
ldmdb r1!, {r7-r9,lr}
subs r12, r12, #1<<16
mode2_4pix2_180 lr
stmia r0!, {r3-r6}
mode2_4pix2_180 r9
stmia r0!, {r3-r6}
mode2_4pix2_180 r8
stmia r0!, {r3-r6}
mode2_4pix_to3 r7, 1
stmia r0!, {r3-r5}
bpl .loop_c2_32c_180
sub r12, r12, #1
adds r12, r12, #1<<16
ldmeqfd sp!, {r4-r11,pc} @ return
.if BORDER_R
add r0, r0, #BORDER_R*4
.endif
sub r1, r1, #64+8
orr r12, #(240/15-1)<<16
b .loop_c2_32c_180
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.global vidClear @ void *to, int lines
vidClear:
stmfd sp!, {lr}
mov r12, #240/16-1
orr r12, r1, r12, lsl #16
mov r1, #0
mov r2, #0
mov r3, #0
mov lr, #0
.loopVidClear:
subs r12, r12, #1<<16
stmia r0!, {r1-r3,lr}
stmia r0!, {r1-r3,lr}
stmia r0!, {r1-r3,lr}
stmia r0!, {r1-r3,lr}
bpl .loopVidClear
sub r12, r12, #1
adds r12, r12, #1<<16
ldmeqfd sp!, {pc} @ return
.if BORDER_R
add r0, r0, #BORDER_R*4
.endif
orr r12, #(240/16-1)<<16
b .loopVidClear
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.equ EExecSetExceptionHandler, (90)
.global my_SetExceptionHandler
my_SetExceptionHandler:
mov ip, lr
swi EExecSetExceptionHandler

View file

@ -1,270 +0,0 @@
#include <e32svr.h> // RDebug
#include "debug.h"
//#define LOG_FILE "C:\\logs\\pico.log"
#define LOG_FILE _L("D:\\pico.log")
#ifdef __WINS__
void ExceptionHandler(TExcType exc) {}
#else
static const wchar_t * const exception_names[] = {
L"General",
L"IntegerDivideByZero",
L"SingleStep",
L"BreakPoint",
L"IntegerOverflow",
L"BoundsCheck",
L"InvalidOpCode",
L"DoubleFault",
L"StackFault",
L"AccessViolation",
L"PrivInstruction",
L"Alignment",
L"PageFault",
L"FloatDenormal",
L"FloatDivideByZero",
L"FloatInexactResult",
L"FloatInvalidOperation",
L"FloatOverflow",
L"FloatStackCheck",
L"FloatUnderflow",
L"Abort",
L"Kill",
L"DataAbort",
L"CodeAbort",
L"MaxNumber",
L"InvalidVector",
L"UserInterrupt",
L"Unknown"
};
#if 0
static void getASpace(TUint *code_start, TUint *code_end, TUint *stack_start, TUint *stack_end)
{
TUint pc, sp;
RChunk chunk;
TFullName chunkname;
TFindChunk findChunk(_L("*"));
asm volatile ("str pc, %0" : "=m" (pc) );
asm volatile ("str sp, %0" : "=m" (sp) );
while( findChunk.Next(chunkname) != KErrNotFound ) {
chunk.Open(findChunk);
if((TUint)chunk.Base()+chunk.Bottom() < pc && pc < (TUint)chunk.Base()+chunk.Top()) {
if(code_start) *code_start = (TUint)chunk.Base()+chunk.Bottom();
if(code_end) *code_end = (TUint)chunk.Base()+chunk.Top();
} else
if((TUint)chunk.Base()+chunk.Bottom() < sp && sp < (TUint)chunk.Base()+chunk.Top()) {
if(stack_start) *stack_start = (TUint)chunk.Base()+chunk.Bottom();
if(stack_end) *stack_end = (TUint)chunk.Base()+chunk.Top();
}
chunk.Close();
}
}
#endif
// tmp
#if defined(__DEBUG_PRINT)
extern "C" char *PDebugMain();
#endif
// our very own exception handler
void ExceptionHandler(TExcType exc)
{
DEBUGPRINT(_L("ExceptionHandler() called!!!")); // this seems to never be called
#if 0
TUint lr, sp, i;
TUint stack_end = 0; // ending address of our stack chunk
TUint code_start = 0, code_end = 0; // starting and ending addresses of our code chunk
TUint guessed_address = 0;
asm volatile ("str lr, %0" : "=m" (lr) );
asm volatile ("str sp, %0" : "=m" (sp) );
// first get some info about the chunks we live in
getASpace(&code_start, &code_end, 0, &stack_end);
// now we begin some black magic tricks
// we go up our stack until we pass our caller address
for(; sp < stack_end; sp += 4)
if(*(TUint *)sp == lr) break;
// there might be mirored caller address
for(i = sp + 4; i < sp + 0x300 && i < stack_end; i += 4)
if(*(TUint *)i == lr) { sp = i; break; }
// aah, it is always 0x9c bytes away from the caller address in my firmware,
// don't know how to detect it in any other way
sp += 0x9c;
guessed_address = *(TUint *)sp;
// output the info
TUint exec_show = exc;
if(exec_show > 27) exec_show = 27;
TPtrC ptrExc((TUint16 *) exception_names[exec_show]);
RDebug::Print(_L("!!!Exception %i (%S) @ 0x%08x (guessed; relative=0x%08x)"), exc, &ptrExc, guessed_address, guessed_address - code_start);
#ifdef __DEBUG_PRINT_FILE
DEBUGPRINT( _L("!!!Exception %i (%S) @ 0x%08x (guessed; relative=0x%08x)"), exc, &ptrExc, guessed_address, guessed_address - code_start);
#endif
TBuf<148> buff1;
TBuf<10> buff2;
buff1.Copy(_L(" guessed stack: "));
for(sp += 4, i = 0; i < 5 && sp < stack_end; sp += 4) {
if((*(TUint *)sp >> 28) == 5) {
if(i++) buff1.Append(_L(", "));
buff2.Format(_L("0x%08x"), *(TUint *)sp);
buff1.Append(buff2);
}
else if(code_start < *(TUint *)sp && *(TUint *)sp < code_end) {
if(i++) buff1.Append(_L(", "));
buff2.Format(_L("0x%08x"), *(TUint *)sp);
buff1.Append(buff2);
buff1.Append(_L(" ("));
buff2.Format(_L("0x%08x"), *(TUint *)sp - code_start);
buff1.Append(buff2);
buff1.Append(_L(")"));
}
}
RDebug::Print(_L("%S"), &buff1);
#ifdef __DEBUG_PRINT_FILE
DEBUGPRINT(_L("%S"), &buff1);
#endif
// tmp
#if defined(__DEBUG_PRINT)
char *ps, *cstr = PDebugMain();
for(ps = cstr; *ps; ps++) {
if(*ps == '\n') {
*ps = 0;
lprintf(cstr);
cstr = ps+1;
}
}
#endif
// RDebug::Print(_L("Stack dump:"));
// asm volatile ("str sp, %0" : "=m" (sp) );
// for(TUint i = sp+0x400; i >= sp-16; i-=4)
// RDebug::Print(_L("%08x: %08x"), i, *(int *)i);
// more descriptive replacement of "KERN-EXEC 3" panic
buff1.Format(_L("K-EX3: %S"), &ptrExc);
User::Panic(buff1, exc);
#endif
}
#endif // ifdef __WINS__
#if 1 // def __DEBUG_PRINT_C
#include <stdarg.h> // va_*
#include <stdio.h> // vsprintf
// debug print from c code
extern "C" void lprintf(const char *format, ...)
{
va_list args;
char buffer[512];
int len;
va_start(args,format);
len = vsprintf(buffer,format,args);
va_end(args);
if (buffer[len-1] == '\n')
buffer[len-1] = 0;
DEBUGPRINT(_L("%S"), DO_CONV(buffer));
}
#endif
#if defined(__DEBUG_PRINT) || defined(__WINS__)
#ifndef __DLL__
// c string dumper for RDebug::Print()
static TBuf<1024> sTextBuffer;
TDesC* DO_CONV(const char* s)
{
TPtrC8 text8((TUint8*) (s));
sTextBuffer.Copy(text8);
return &sTextBuffer;
}
#endif
#ifdef __DEBUG_PRINT_FILE
#include <f32file.h>
//static RFile logFile;
// static TBool logInited = 0;
RMutex logMutex;
static void debugPrintFileInit()
{
// try to open
logMutex.CreateLocal();
/*RFs fserv;
fserv.Connect();
RFile logFile;
logFile.Replace(fserv, LOG_FILE, EFileWrite|EFileShareAny);
logFile.Close();
fserv.Close();*/
}
// debug print to file
void debugPrintFile(TRefByValue<const TDesC> aFmt, ...)
{
if (logMutex.Handle() <= 0) debugPrintFileInit();
logMutex.Wait();
RFs fserv;
fserv.Connect();
TTime now; now.UniversalTime();
TBuf<512> tmpBuff;
TBuf8<512> tmpBuff8;
TInt size, res;
RThread thisThread;
RFile logFile;
res = logFile.Open(fserv, LOG_FILE, EFileWrite|EFileShareAny);
if(res) goto fail1;
logFile.Size(size); logFile.Seek(ESeekStart, size);
now.FormatL(tmpBuff, _L("%H:%T:%S.%C: "));
tmpBuff8.Copy(tmpBuff);
logFile.Write(tmpBuff8);
tmpBuff8.Format(TPtr8((TUint8 *)"%03i: ", 6, 6), (TInt32) thisThread.Id());
logFile.Write(tmpBuff8);
VA_LIST args;
VA_START(args, aFmt);
tmpBuff.FormatList(aFmt, args);
VA_END(args);
tmpBuff8.Copy(tmpBuff);
logFile.Write(tmpBuff8);
logFile.Write(TPtrC8((TUint8 const *) "\n"));
logFile.Flush();
logFile.Close();
fail1:
thisThread.Close();
fserv.Close();
logMutex.Signal();
}
#endif
#endif

View file

@ -1,27 +0,0 @@
#include <e32std.h>
#define __DEBUG_PRINT_C
#define __DEBUG_PRINT_FILE
#if defined(__DEBUG_PRINT) || defined(__WINS__)
#include <e32svr.h> // RDebug
#ifdef __DEBUG_PRINT_FILE
void debugPrintFile(TRefByValue<const TDesC> aFmt, ...);
#define DEBUGPRINT debugPrintFile
#else
#define DEBUGPRINT RDebug::Print
#endif
TDesC* DO_CONV(const char* s);
#ifdef __DEBUG_PRINT_C
#ifdef __cplusplus
extern "C"
#endif
void lprintf(const char *format, ...);
#endif
#else
#define DEBUGPRINT(x...)
#undef __DEBUG_PRINT_C
#undef __DEBUG_PRINT_FILE
#endif
void ExceptionHandler(TExcType exc);

View file

@ -1,921 +0,0 @@
// mainloop with window server event handling
// event polling mechnism was taken from
// Peter van Sebille's projects
// (c) Copyright 2006, notaz
// All Rights Reserved
#include <e32base.h>
#include <hal.h>
#include <e32keys.h>
#include <w32std.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include "debug.h"
#include "../Engine.h"
#include <pico/pico_int.h>
#include "../../common/emu.h"
#include "../emu.h"
#include "vid.h"
#include "PolledAS.h"
//#include "audio.h"
#include "audio_mediaserver.h"
//#include <ezlib.h>
#include <zlib/zlib.h>
//#define BENCHMARK
// scancodes we care about
enum TUsedScanCodes {
EStdKeyM600JogUp = EStdKeyDevice1,
EStdKeyM600JogDown = EStdKeyDevice2,
};
static unsigned char keyFlags[256]; // lsb->msb: key_down, pulse_only, ?, ?, ?, ?, not_configurable, disabled
static unsigned char pressedKeys[11]; // List of pressed key scancodes, up to 10
// list of areas
TPicoAreaConfigEntry areaConfig[] = {
{ TRect( 0, 0, 0, 0) },
// small corner bottons
{ TRect( 0, 0, 15, 15) },
{ TRect(224, 0, 239, 15) },
{ TRect( 0, 304, 15, 319) },
{ TRect(224, 304, 239, 319) },
// normal buttons
{ TRect( 0, 0, 79, 63) },
{ TRect( 80, 0, 159, 63) },
{ TRect(160, 0, 239, 63) },
{ TRect( 0, 64, 79, 127) },
{ TRect( 80, 64, 159, 127) },
{ TRect(160, 64, 239, 127) },
{ TRect( 0, 128, 79, 191) },
{ TRect( 80, 128, 159, 191) },
{ TRect(160, 128, 239, 191) },
{ TRect( 0, 192, 79, 255) },
{ TRect( 80, 192, 159, 255) },
{ TRect(160, 192, 239, 255) },
{ TRect( 0, 256, 79, 319) },
{ TRect( 80, 256, 159, 319) },
{ TRect(160, 256, 239, 319) },
{ TRect( 0, 0, 0, 0) }
};
// PicoPad[] format: SACB RLDU
const char *actionNames[] = {
"UP", "DOWN", "LEFT", "RIGHT", "B", "C", "A", "START",
0, 0, 0, 0, 0, 0, 0, 0, // Z, Y, X, MODE (enabled only when needed), ?, ?, ?, ?
0, 0, 0, 0, "VOLUME@UP", "VOLUME@DOWN", "NEXT@SAVE@SLOT", "PREV@SAVE@SLOT", // ?, ?, ?, ?, vol_up, vol_down, next_slot, prev_slot
0, 0, "PAUSE@EMU", "SAVE@STATE", "LOAD@STATE", 0, 0, "DONE" // ?, switch_renderer, [...], "FRAMESKIP@8", "AUTO@FRAMESKIP"
};
// globals are allowed, so why not to (ab)use them?
//TInt machineUid = 0;
int gamestate = PGS_Paused, gamestate_next = PGS_Paused;
char *loadrom_fname = NULL;
int loadrom_result = 0;
static timeval noticeMsgTime = { 0, 0 }; // when started showing
static CGameAudioMS *gameAudio = 0; // the audio object itself
static int reset_timing = 0;
static int pico_was_reset = 0;
extern RSemaphore initSemaphore;
extern RSemaphore pauseSemaphore;
extern RSemaphore loadWaitSemaphore;
// some forward declarations
static void MainInit();
static void MainExit();
static void DumpMemInfo();
class TPicoDirectScreenAccess : public MDirectScreenAccess
{
public: // implements MDirectScreenAccess
void Restart(RDirectScreenAccess::TTerminationReasons aReason);
public: // implements MAbortDirectScreenAccess
void AbortNow(RDirectScreenAccess::TTerminationReasons aReason);
};
// just for a nicer grouping of WS related stuff
class CGameWindow
{
public:
static void ConstructResourcesL(void);
static void FreeResources(void);
static void DoKeys(void);
static void DoKeysConfig(TUint &which);
static void RunEvents(TUint32 which);
static RWsSession* iWsSession;
static RWindowGroup iWsWindowGroup;
static RWindow iWsWindow;
static CWsScreenDevice* iWsScreen;
static CWindowGc* iWindowGc;
static TRequestStatus iWsEventStatus;
// static TThreadId iLauncherThreadId;
// static RDirectScreenAccess* iDSA;
// static TRequestStatus iDSAstatus;
static TPicoDirectScreenAccess iPDSA;
static CDirectScreenAccess* iDSA;
};
static void updateSound(int len)
{
PsndOut = gameAudio->NextFrameL(len);
if(!PsndOut) { // sound output problems?
strcpy(noticeMsg, "SOUND@OUTPUT@ERROR;@SOUND@DISABLED");
gettimeofday(&noticeMsgTime, 0);
}
}
static void SkipFrame(void)
{
PicoSkipFrame=1;
PicoFrame();
PicoSkipFrame=0;
}
static void simpleWait(int thissec, int lim_time)
{
struct timeval tval;
int sleep = 0;
gettimeofday(&tval, 0);
if(thissec != tval.tv_sec) tval.tv_usec+=1000000;
sleep = lim_time - tval.tv_usec - 2000;
if (sleep > 0) {
// User::After((sleep = lim_time - tval.tv_usec));
User::AfterHighRes(sleep);
}
}
static void TargetEpocGameL()
{
char buff[24]; // fps count c string
struct timeval tval; // timing
int thissec = 0, frames_done = 0, frames_shown = 0;
int target_fps, target_frametime;
int i, lim_time;
MainInit();
buff[0] = 0;
// try to start pico
DEBUGPRINT(_L("PicoInit()"));
PicoInit();
PicoDrawSetColorFormat(2);
PicoWriteSound = updateSound;
// loop?
for(;;)
{
if (gamestate == PGS_Running)
{
#ifdef __DEBUG_PRINT
TInt mem, cells = User::CountAllocCells();
User::AllocSize(mem);
DEBUGPRINT(_L("worker: cels=%d, size=%d KB"), cells, mem/1024);
#endif
// switch context to other thread
User::After(50000);
// prepare window and stuff
CGameWindow::ConstructResourcesL();
// if the system has something to do, it should better do it now
User::After(50000);
//CPolledActiveScheduler::Instance()->Schedule();
// pal/ntsc might have changed, reset related stuff
if(Pico.m.pal) {
target_fps = 50;
if(!noticeMsgTime.tv_sec) strcpy(noticeMsg, "PAL@SYSTEM@/@50@FPS");
} else {
target_fps = 60;
if(!noticeMsgTime.tv_sec) strcpy(noticeMsg, "NTSC@SYSTEM@/@60@FPS");
}
target_frametime = 1000000/target_fps;
if (!noticeMsgTime.tv_sec && pico_was_reset)
gettimeofday(&noticeMsgTime, 0);
// prepare CD buffer
if (PicoAHW & PAHW_MCD) PicoCDBufferInit();
pico_was_reset = 0;
reset_timing = 1;
while (gamestate == PGS_Running)
{
gettimeofday(&tval, 0);
if(reset_timing) {
reset_timing = 0;
thissec = tval.tv_sec;
frames_done = tval.tv_usec/target_frametime;
}
// show notice message?
char *notice = 0;
if(noticeMsgTime.tv_sec) {
if((tval.tv_sec*1000000+tval.tv_usec) - (noticeMsgTime.tv_sec*1000000+noticeMsgTime.tv_usec) > 2000000) // > 2.0 sec
noticeMsgTime.tv_sec = noticeMsgTime.tv_usec = 0;
else notice = noticeMsg;
}
// second changed?
if (thissec != tval.tv_sec)
{
#ifdef BENCHMARK
static int bench = 0, bench_fps = 0, bench_fps_s = 0, bfp = 0, bf[4];
if(++bench == 10) {
bench = 0;
bench_fps_s = bench_fps;
bf[bfp++ & 3] = bench_fps;
bench_fps = 0;
}
bench_fps += frames_shown;
sprintf(buff, "%02i/%02i/%02i", frames_shown, bench_fps_s, (bf[0]+bf[1]+bf[2]+bf[3])>>2);
#else
if (currentConfig.EmuOpt & EOPT_SHOW_FPS)
sprintf(buff, "%02i/%02i", frames_shown, frames_done);
#endif
thissec = tval.tv_sec;
if(PsndOut == 0 && currentConfig.Frameskip >= 0) {
frames_done = frames_shown = 0;
} else {
// it is quite common for this implementation to leave 1 fame unfinished
// when second changes, but we don't want buffer to starve.
if(PsndOut && frames_done < target_fps && frames_done > target_fps-5) {
SkipFrame(); frames_done++;
}
frames_done -= target_fps; if (frames_done < 0) frames_done = 0;
frames_shown -= target_fps; if (frames_shown < 0) frames_shown = 0;
if (frames_shown > frames_done) frames_shown = frames_done;
}
User::ResetInactivityTime();
}
lim_time = (frames_done+1) * target_frametime;
if (currentConfig.Frameskip >= 0) // frameskip enabled
{
for (i = 0; i < currentConfig.Frameskip && gamestate == PGS_Running; i++)
{
CGameWindow::DoKeys();
SkipFrame(); frames_done++;
if (PsndOut) { // do framelimitting if sound is enabled
gettimeofday(&tval, 0);
if(thissec != tval.tv_sec) tval.tv_usec+=1000000;
if(tval.tv_usec < lim_time) { // we are too fast
simpleWait(thissec, lim_time);
}
}
lim_time += target_frametime;
}
}
else if(tval.tv_usec > lim_time) { // auto frameskip
// no time left for this frame - skip
CGameWindow::DoKeys();
SkipFrame(); frames_done++;
continue;
}
// we might have lost focus already
if (gamestate != PGS_Running) break;
CGameWindow::DoKeys();
PicoFrame();
// check time
gettimeofday(&tval, 0);
if(thissec != tval.tv_sec) tval.tv_usec+=1000000;
// sleep if we are still too fast
if(PsndOut != 0 || currentConfig.Frameskip < 0)
{
// TODO: check if User::After() is accurate
gettimeofday(&tval, 0);
if(thissec != tval.tv_sec) tval.tv_usec+=1000000;
if(tval.tv_usec < lim_time)
{
// we are too fast
simpleWait(thissec, lim_time);
}
}
CPolledActiveScheduler::Instance()->Schedule();
if (gamestate != PGS_Paused)
vidDrawFrame(notice, buff, frames_shown);
frames_done++; frames_shown++;
} // while
if (PicoAHW & PAHW_MCD) PicoCDBufferFree();
// save SRAM
if ((currentConfig.EmuOpt & EOPT_EN_SRAM) && SRam.changed) {
emu_save_load_game(0, 1);
SRam.changed = 0;
}
CPolledActiveScheduler::Instance()->Schedule();
CGameWindow::FreeResources();
}
else if(gamestate == PGS_Reset)
{
PicoReset();
pico_was_reset = 1;
gamestate = PGS_Running;
}
else if(gamestate == PGS_ReloadRom)
{
loadrom_result = emu_reload_rom(loadrom_fname);
pico_was_reset = 1;
if (loadrom_result)
gamestate = PGS_Running;
else {
extern char menuErrorMsg[];
gamestate = PGS_Paused;
lprintf("%s\n", menuErrorMsg);
}
DEBUGPRINT(_L("done loading ROM, retval=%i"), loadrom_result);
loadWaitSemaphore.Signal();
User::After(50000);
}
else if(gamestate == PGS_Paused) {
DEBUGPRINT(_L("pausing.."));
pauseSemaphore.Wait();
}
else if(gamestate == PGS_KeyConfig)
{
// switch context to other thread
User::After(50000);
// prepare window and stuff
CGameWindow::ConstructResourcesL();
TUint whichAction = 0;
while(gamestate == PGS_KeyConfig) {
CGameWindow::DoKeysConfig(whichAction);
CPolledActiveScheduler::Instance()->Schedule();
if (gamestate != PGS_Paused)
vidKeyConfigFrame(whichAction);
User::After(150000);
}
emu_write_config(0);
CGameWindow::FreeResources();
} else if(gamestate == PGS_Quit) {
break;
}
}
// this thread has to close it's own handles,
// other one will crash trying to do that
PicoExit();
MainExit();
}
// main initialization
static void MainInit()
{
DEBUGPRINT(_L("\r\n\r\nstarting.."));
DEBUGPRINT(_L("CPolledActiveScheduler::NewL()"));
CPolledActiveScheduler::NewL(); // create Polled AS for the sound engine
// HAL::Get(HALData::EMachineUid, machineUid); // find out the machine UID
DumpMemInfo();
// if (pauseSemaphore.Handle() <= 0)
// pauseSemaphore.CreateLocal(0);
DEBUGPRINT(_L("initSemaphore.Signal()"));
initSemaphore.Signal();
}
// does not return
static void MainExit()
{
RThread thisThread;
DEBUGPRINT(_L("%i: cleaning up.."), (TInt32) thisThread.Id());
// pauseSemaphore.Close();
if(gameAudio) delete gameAudio;
// Polled AS
delete CPolledActiveScheduler::Instance();
}
static void DumpMemInfo()
{
TInt ramSize, ramSizeFree, romSize;
HAL::Get(HALData::EMemoryRAM, ramSize);
HAL::Get(HALData::EMemoryRAMFree, ramSizeFree);
HAL::Get(HALData::EMemoryROM, romSize);
DEBUGPRINT(_L("ram=%dKB, ram_free=%dKB, rom=%dKB"), ramSize/1024, ramSizeFree/1024, romSize/1024);
}
extern "C" TInt my_SetExceptionHandler(TInt, TExceptionHandler, TUint32);
TInt EmuThreadFunction(TAny*)
{
TInt ret;
const TUint32 exs = KExceptionAbort|KExceptionKill|KExceptionUserInterrupt|KExceptionFpe|KExceptionFault|KExceptionInteger|KExceptionDebug;
DEBUGPRINT(_L("EmuThreadFunction(), def ExceptionHandler %08x, my %08x"),
User::ExceptionHandler(), ExceptionHandler);
User::SetJustInTime(1);
ret = User::SetExceptionHandler(ExceptionHandler, exs/*(TUint32) -1*/); // does not work :(
// my_SetExceptionHandler(KCurrentThreadHandle, ExceptionHandler, 0xffffffff);
DEBUGPRINT(_L("SetExceptionHandler %i, %08x"), ret, User::ExceptionHandler());
User::ModifyExceptionMask(0, exs);
//TInt pc, sp;
//asm volatile ("str pc, %0" : "=m" (pc) );
//asm volatile ("str sp, %0" : "=m" (sp) );
//RDebug::Print(_L("executing @ 0x%08x, sp=0x%08x"), pc, sp);
/*
RDebug::Print(_L("Base Bottom Top Size RW Name"));
TBuf<4> l_r(_L("R")), l_w(_L("W")), l_d(_L("-"));
RChunk chunk;
TFullName chunkname;
TFindChunk findChunk(_L("*"));
while( findChunk.Next(chunkname) != KErrNotFound ) {
chunk.Open(findChunk);
RDebug::Print(_L("%08x %08x %08x %08x %S%S %S"), chunk.Base(), chunk.Base()+chunk.Bottom(), chunk.Base()+chunk.Top(), chunk.Size(), chunk.IsReadable() ? &l_r : &l_d, chunk.IsWritable() ? &l_w : &l_d, &chunkname);
chunk.Close();
}
*/
// can't do that, will crash here
// if(cleanup) {
// DEBUGPRINT(_L("found old CTrapCleanup, deleting.."));
// delete cleanup;
// }
CTrapCleanup *cleanup = CTrapCleanup::New();
TRAPD(error, TargetEpocGameL());
__ASSERT_ALWAYS(!error, User::Panic(_L("PicoDrive"), error));
delete cleanup;
DEBUGPRINT(_L("exitting.."));
return 1;
}
void TPicoDirectScreenAccess::Restart(RDirectScreenAccess::TTerminationReasons aReason)
{
DEBUGPRINT(_L("TPicoDirectScreenAccess::Restart(%i)"), aReason);
// if (CGameWindow::iDSA) {
// TRAPD(error, CGameWindow::iDSA->StartL());
// if (error) DEBUGPRINT(_L("iDSA->StartL() error: %i"), error);
// }
}
void TPicoDirectScreenAccess::AbortNow(RDirectScreenAccess::TTerminationReasons aReason)
{
DEBUGPRINT(_L("TPicoDirectScreenAccess::AbortNow(%i)"), aReason);
// the WS wants us to stop, so let's obey
gamestate = PGS_Paused;
}
void CGameWindow::ConstructResourcesL()
{
DEBUGPRINT(_L("ConstructResourcesL()"));
// connect to window server
// tried to create it globally and not re-connect everytime,
// but my window started to lose focus strangely
iWsSession = new(ELeave) RWsSession();
User::LeaveIfError(iWsSession->Connect());
// * Tell the Window Server not to mess about with our process priority
// * Also, because of the way legacy games are written, they never sleep
// * and thus never voluntarily yield the CPU. We set our process priority
// * to EPriorityForeground and hope that a Telephony application on
// * this device runs at EPriorityForeground as well. If not, tough! ;-)
iWsSession->ComputeMode(RWsSession::EPriorityControlDisabled);
RProcess me;
me.SetPriority(EPriorityForeground);
iWsScreen = new(ELeave) CWsScreenDevice(*iWsSession);
User::LeaveIfError(iWsScreen->Construct());
// User::LeaveIfError(iWsScreen->CreateContext(iWindowGc));
iWsWindowGroup = RWindowGroup(*iWsSession);
User::LeaveIfError(iWsWindowGroup.Construct((TUint32)&iWsWindowGroup));
//iWsWindowGroup.SetOrdinalPosition(0);
//iWsWindowGroup.SetName(KServerWGName);
iWsWindowGroup.EnableScreenChangeEvents(); // flip events (EEventScreenDeviceChanged)
iWsWindowGroup.EnableFocusChangeEvents(); // EEventFocusGroupChanged
iWsWindowGroup.SetOrdinalPosition(0, 1); // TInt aPos, TInt aOrdinalPriority
iWsWindow=RWindow(*iWsSession);
User::LeaveIfError(iWsWindow.Construct(iWsWindowGroup, (TUint32)&iWsWindow));
iWsWindow.SetSize(iWsScreen->SizeInPixels());
iWsWindow.PointerFilter(EPointerFilterDrag, 0);
iWsWindow.SetPointerGrab(ETrue);
iWsWindow.SetVisible(ETrue);
iWsWindow.Activate();
#if 0
// request access through RDirectScreenAccess api, but don't care about the result
// hangs?
RRegion *dsa_region = 0;
iDSA = new(ELeave) RDirectScreenAccess(*iWsSession);
if(iDSA->Construct() == KErrNone)
iDSA->Request(dsa_region, iDSAstatus, iWsWindow);
DEBUGPRINT(_L("DSA: %i"), dsa_region ? dsa_region->Count() : -1);
#endif
TInt ret;
// request access through CDirectScreenAccess
iDSA = CDirectScreenAccess::NewL(*iWsSession, *iWsScreen, iWsWindow, iPDSA);
// now get the screenbuffer
TScreenInfoV01 screenInfo;
TPckg<TScreenInfoV01> sI(screenInfo);
UserSvr::ScreenInfo(sI);
if(!screenInfo.iScreenAddressValid)
User::Leave(KErrNotSupported);
DEBUGPRINT(_L("framebuffer=0x%08x (%dx%d)"), screenInfo.iScreenAddress,
screenInfo.iScreenSize.iWidth, screenInfo.iScreenSize.iHeight);
// vidInit
DEBUGPRINT(_L("vidInit()"));
ret = vidInit((void *)screenInfo.iScreenAddress, 0);
DEBUGPRINT(_L("vidInit() done (%i)"), ret);
User::LeaveIfError(ret);
memset(keyFlags, 0, 256);
keyFlags[EStdKeyM600JogUp] = keyFlags[EStdKeyM600JogDown] = 2; // add "pulse only" for jog up/down
keyFlags[EStdKeyOff] = 0x40; // not configurable
// try to start the audio engine
static int PsndRate_old = 0, PicoOpt_old = 0, pal_old = 0;
if (gamestate == PGS_Running && (currentConfig.EmuOpt & EOPT_EN_SOUND))
{
TInt err = 0;
if(PsndRate != PsndRate_old || (PicoOpt&11) != (PicoOpt_old&11) || Pico.m.pal != pal_old) {
// if rate changed, reset all enabled chips, else reset only those chips, which were recently enabled
//sound_reset(PsndRate != PsndRate_old ? PicoOpt : (PicoOpt&(PicoOpt^PicoOpt_old)));
PsndRerate(1);
}
if(!gameAudio || PsndRate != PsndRate_old || ((PicoOpt&8) ^ (PicoOpt_old&8)) || Pico.m.pal != pal_old) { // rate or stereo or pal/ntsc changed
if(gameAudio) delete gameAudio; gameAudio = 0;
DEBUGPRINT(_L("starting audio: %i len: %i stereo: %i, pal: %i"), PsndRate, PsndLen, PicoOpt&8, Pico.m.pal);
TRAP(err, gameAudio = CGameAudioMS::NewL(PsndRate, (PicoOpt&8) ? 1 : 0,
Pico.m.pal ? 50 : 60, currentConfig.volume));
}
if( gameAudio) {
TRAP(err, PsndOut = gameAudio->ResumeL());
}
if(err) {
if(gameAudio) delete gameAudio;
gameAudio = 0;
PsndOut = 0;
strcpy(noticeMsg, "SOUND@STARTUP@FAILED");
gettimeofday(&noticeMsgTime, 0);
}
PsndRate_old = PsndRate;
PicoOpt_old = PicoOpt;
pal_old = Pico.m.pal;
} else {
if(gameAudio) delete gameAudio;
gameAudio = 0;
PsndOut = 0;
}
CPolledActiveScheduler::Instance()->Schedule();
// start key WS event polling
iWsSession->EventReady(&iWsEventStatus);
iWsSession->Flush(); // check: short hang in UIQ2
User::After(1);
// I don't know why but the Window server sometimes hangs completely (hanging the phone too) after calling StartL()
// Is this a sync broblem? weird bug?
TRAP(ret, iDSA->StartL());
if (ret) DEBUGPRINT(_L("iDSA->StartL() error: %i"), ret);
// User::After(1);
// CPolledActiveScheduler::Instance()->Schedule();
DEBUGPRINT(_L("CGameWindow::ConstructResourcesL() finished."));
}
// this may be run even if there is nothing to free
void CGameWindow::FreeResources()
{
if(gameAudio) gameAudio->Pause();
//DEBUGPRINT(_L("CPolledActiveScheduler::Instance(): %08x"), CPolledActiveScheduler::Instance());
if(CPolledActiveScheduler::Instance())
CPolledActiveScheduler::Instance()->Schedule();
#if 0
// free RDirectScreenAccess stuff (seems to be deleted automatically after crash?)
if(iDSA) {
iDSA->Cancel();
iDSA->Close();
delete iDSA;
}
iDSA = NULL;
#endif
if(iDSA) delete iDSA;
iDSA = 0;
if(iWsSession->WsHandle() > 0 && iWsEventStatus != KRequestPending) // TODO: 2 UIQ2 (?)
iWsSession->EventReadyCancel();
if(iWsWindow.WsHandle() > 0)
iWsWindow.Close();
if(iWsWindowGroup.WsHandle() > 0)
iWsWindowGroup.Close();
// these must be deleted before calling iWsSession->Close()
if(iWsScreen) {
delete iWsScreen;
iWsScreen = NULL;
}
if(iWsSession->WsHandle() > 0) {
iWsSession->Close();
delete iWsSession;
}
vidFree();
}
void CGameWindow::DoKeys(void)
{
TWsEvent iWsEvent;
TInt iWsEventType;
unsigned long allActions = 0;
static unsigned long areaActions = 0, forceUpdate = 0;
int i, nEvents;
for(nEvents = 0; iWsEventStatus != KRequestPending; nEvents++)
{
iWsSession->GetEvent(iWsEvent);
iWsEventType = iWsEvent.Type();
// pointer events?
if(iWsEventType == EEventPointer) {
if(iWsEvent.Pointer()->iType == TPointerEvent::EButton1Up) {
areaActions = 0; // remove all directionals
} else { // if(iWsEvent.Pointer()->iType == TPointerEvent::EButton1Down) {
TPoint p = iWsEvent.Pointer()->iPosition;
const TPicoAreaConfigEntry *e = areaConfig + 1;
for(i = 0; !e->rect.IsEmpty(); e++, i++)
if(e->rect.Contains(p)) {
areaActions = currentConfig.KeyBinds[i+256];
break;
}
//DEBUGPRINT(_L("pointer event: %i %i"), p.iX, p.iY);
}
}
else if(iWsEventType == EEventKeyDown || iWsEventType == EEventKeyUp) {
TInt iScanCode = iWsEvent.Key()->iScanCode;
//DEBUGPRINT(_L("key event: 0x%02x"), iScanCode);
if(iScanCode < 256)
{
if(iWsEventType == EEventKeyDown) {
keyFlags[iScanCode] |= 1;
for(i=0; i < 10; i++) {
if( pressedKeys[i] == (TUint8) iScanCode) break;
if(!pressedKeys[i]) { pressedKeys[i] = (TUint8) iScanCode; break; }
}
} else if(!(keyFlags[iScanCode]&2)) {
keyFlags[iScanCode] &= ~1;
for(i=0; i < 10; i++) {
if(pressedKeys[i] == (TUint8) iScanCode) { pressedKeys[i] = 0; break; }
}
}
// power?
if(iScanCode == EStdKeyOff) gamestate = PGS_Paused;
} else {
DEBUGPRINT(_L("weird scancode: 0x%02x"), iScanCode);
}
}
else if(iWsEventType == EEventScreenDeviceChanged) {
// ???
//User::After(500000);
//reset_timing = 1;
DEBUGPRINT(_L("EEventScreenDeviceChanged, focus: %i, our: %i"),
iWsSession->GetFocusWindowGroup(), iWsWindowGroup.Identifier());
}
else if(iWsEventType == EEventFocusGroupChanged) {
TInt focusGrpId = iWsSession->GetFocusWindowGroup();
DEBUGPRINT(_L("EEventFocusGroupChanged: %i, our: %i"),
focusGrpId, iWsWindowGroup.Identifier());
// if it is not us and not launcher that got focus, pause emu
if(focusGrpId != iWsWindowGroup.Identifier())
gamestate = PGS_Paused;
}
iWsEventStatus = KRequestPending;
iWsSession->EventReady(&iWsEventStatus);
}
if(nEvents || forceUpdate) {
allActions = areaActions;
forceUpdate = 0;
// add all pushed button actions
for(i = 9; i >= 0; i--) {
int scan = pressedKeys[i];
if(scan) {
if(keyFlags[scan] & 1) allActions |= currentConfig.KeyBinds[scan];
if((keyFlags[scan]& 3)==3) forceUpdate = 1;
if(keyFlags[scan] & 2) keyFlags[scan] &= ~1;
}
}
PicoPad[0] = (unsigned short) allActions;
if(allActions & 0xFFFF0000) {
RunEvents(allActions >> 16);
areaActions = 0;
}
}
if (movie_data) emu_updateMovie();
}
void CGameWindow::DoKeysConfig(TUint &which)
{
TWsEvent iWsEvent;
int i;
while(iWsEventStatus != KRequestPending)
{
TUint currentActCode = 1 << which;
iWsSession->GetEvent(iWsEvent);
// pointer events?
if(iWsEvent.Type() == EEventPointer) {
TPoint p = iWsEvent.Pointer()->iPosition;
TRect prev(56, 0, 120, 26);
TRect next(120, 0, 180, 26);
if(iWsEvent.Pointer()->iType == TPointerEvent::EButton1Down) {
if(prev.Contains(p)) do { which = (which-1) & 0x1F; } while(!actionNames[which]);
else if(next.Contains(p)) do { which = (which+1) & 0x1F; } while(!actionNames[which]);
else if(which == 31) gamestate = PGS_Paused; // done
else {
const TPicoAreaConfigEntry *e = areaConfig + 1;
for(i = 0; e->rect != TRect(0,0,0,0); e++, i++)
if(e->rect.Contains(p)) {
currentConfig.KeyBinds[i+256] ^= currentActCode;
break;
}
}
}
}
else if(iWsEvent.Type() == EEventKeyDown || iWsEvent.Type() == EEventKeyUp)
{
TUint scan = (TUint) iWsEvent.Key()->iScanCode;
// key events?
if(iWsEvent.Type() == EEventKeyDown) {
if(which == 31) {
gamestate = PGS_Paused;
} else if (scan < 256) {
if(!(keyFlags[scan]&0x40)) currentConfig.KeyBinds[scan] ^= currentActCode;
}
}
// power?
if(iWsEvent.Key()->iScanCode == EStdKeyOff) gamestate = PGS_Paused;
}
else if(iWsEvent.Type() == EEventFocusGroupChanged) {
TInt focusGrpId = iWsSession->GetFocusWindowGroup();
// if we lost focus, exit config mode
if(focusGrpId != iWsWindowGroup.Identifier())
gamestate = PGS_Paused;
}
// iWsEventStatus = KRequestPending;
iWsSession->EventReady(&iWsEventStatus);
}
}
void CGameWindow::RunEvents(TUint32 which)
{
if (which & 0x4000) currentConfig.Frameskip = -1;
if (which & 0x2000) currentConfig.Frameskip = 8;
if (which & 0x1800) { // save or load (but not both)
if(PsndOut) gameAudio->Pause(); // this may take a while, so we pause sound output
vidDrawNotice((which & 0x1000) ? "LOADING@GAME" : "SAVING@GAME");
emu_save_load_game(which & 0x1000, 0);
if(PsndOut) PsndOut = gameAudio->ResumeL();
reset_timing = 1;
}
if (which & 0x0400) gamestate = PGS_Paused;
if (which & 0x0200) { // switch renderer
if (!(currentConfig.scaling == TPicoConfig::PMFit &&
(currentConfig.rotation == TPicoConfig::PRot0 || currentConfig.rotation == TPicoConfig::PRot180)))
{
PicoOpt^=0x10;
vidInit(0, 1);
strcpy(noticeMsg, (PicoOpt&0x10) ? "ALT@RENDERER" : "DEFAULT@RENDERER");
gettimeofday(&noticeMsgTime, 0);
}
}
if(which & 0x00c0) {
if(which&0x0080) {
state_slot -= 1;
if(state_slot < 0) state_slot = 9;
} else {
state_slot += 1;
if(state_slot > 9) state_slot = 0;
}
sprintf(noticeMsg, "SAVE@SLOT@%i@SELECTED", state_slot);
gettimeofday(&noticeMsgTime, 0);
}
if ((which & 0x0030) && gameAudio != NULL) {
currentConfig.volume = gameAudio->ChangeVolume((which & 0x0010) ? 1 : 0);
sprintf(noticeMsg, "VOL@%02i@", currentConfig.volume);
gettimeofday(&noticeMsgTime, 0);
}
}
extern "C" void plat_status_msg(const char *format, ...)
{
va_list vl;
char *p;
va_start(vl, format);
vsnprintf(noticeMsg, sizeof(noticeMsg), fmt, vl);
va_end(vl);
p = noticeMsg;
while (*p) {
if (*p == ' ') *p = '@';
if (*p < '0' || *p > 'Z') { *p = 0; break; }
p++;
}
gettimeofday(&noticeMsgTime, 0);
}
// static class members
RWsSession* CGameWindow::iWsSession;
RWindowGroup CGameWindow::iWsWindowGroup;
RWindow CGameWindow::iWsWindow;
CWsScreenDevice* CGameWindow::iWsScreen = NULL;
CWindowGc* CGameWindow::iWindowGc = NULL;
TRequestStatus CGameWindow::iWsEventStatus = KRequestPending;
//RDirectScreenAccess* CGameWindow::iDSA;
//TRequestStatus CGameWindow::iDSAstatus = KRequestPending;
TPicoDirectScreenAccess CGameWindow::iPDSA;
CDirectScreenAccess* CGameWindow::iDSA = NULL;

View file

@ -1,269 +0,0 @@
/*******************************************************************
*
* File: PolledAS.cpp
*
* Author: Peter van Sebille (peter@yipton.net)
*
* (c) Copyright 2002, Peter van Sebille
* All Rights Reserved
*
*******************************************************************/
/*
* Oh Lord, forgive me for I have sinned.
* In their infinite wisdom, Symbian Engineers have decided that
* the Active Scheduler's queue of Active Objects is private
* and no getters are provided... sigh.
* This mere mortal will have to excercise the power of C pre-processor
* once more to circumvent the will of the gods.
*/
#include <e32std.h>
// from e32base.h
class CBase
{
public:
/**
Default constructor
*/
inline CBase() {}
IMPORT_C virtual ~CBase();
inline TAny* operator new(TUint aSize, TAny* aBase) __NO_THROW { Mem::FillZ(aBase, aSize); return aBase; }
inline TAny* operator new(TUint aSize) __NO_THROW { return User::AllocZ(aSize); }
inline TAny* operator new(TUint aSize, TLeave) { return User::AllocZL(aSize); }
inline TAny* operator new(TUint aSize, TUint aExtraSize) { return User::AllocZ(aSize + aExtraSize); }
inline TAny* operator new(TUint aSize, TLeave, TUint aExtraSize) { return User::AllocZL(aSize + aExtraSize); }
IMPORT_C static void Delete(CBase* aPtr);
protected:
IMPORT_C virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1);
private:
CBase(const CBase&);
CBase& operator=(const CBase&);
private:
};
class TRequestStatusFaked
{
public:
inline TRequestStatusFaked() : iFlags(0) {};
inline TRequestStatusFaked(TInt aVal) : iStatus(aVal), iFlags(aVal==KRequestPending ? TRequestStatusFaked::ERequestPending : 0) {}
/* inline TInt operator=(TInt aVal);
inline TBool operator==(TInt aVal) const;
*/
inline TBool operator!=(TInt aVal) const {return(iStatus!=aVal);}
/*
inline TBool operator>=(TInt aVal) const;
inline TBool operator<=(TInt aVal) const;
inline TBool operator>(TInt aVal) const;
inline TBool operator<(TInt aVal) const;
inline TInt Int() const;
private:
*/
enum
{
EActive = 1, //bit0
ERequestPending = 2, //bit1
};
TInt iStatus;
TUint iFlags;
friend class CActive;
friend class CActiveScheduler;
friend class CServer2;
};
class CActive : public CBase
{
public:
enum TPriority
{
EPriorityIdle=-100,
EPriorityLow=-20,
EPriorityStandard=0,
EPriorityUserInput=10,
EPriorityHigh=20,
};
public:
IMPORT_C ~CActive();
IMPORT_C void Cancel();
IMPORT_C void Deque();
IMPORT_C void SetPriority(TInt aPriority);
inline TBool IsActive() const {return(iStatus.iFlags&TRequestStatus::EActive);}
inline TBool IsAdded() const {return(iLink.iNext!=NULL);}
inline TInt Priority() const {return iLink.iPriority;}
protected:
IMPORT_C CActive(TInt aPriority);
IMPORT_C void SetActive();
virtual void DoCancel() =0;
virtual void RunL() =0;
IMPORT_C virtual TInt RunError(TInt aError);
protected:
IMPORT_C virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1);
public:
TRequestStatusFaked iStatus; // hope this will work
private:
// TBool iActive;
TPriQueLink iLink;
TAny* iSpare;
friend class CActiveScheduler;
friend class CServer;
friend class CServer2;
friend class CPrivatePolledActiveScheduler; // added
};
class CActiveScheduler : public CBase
{
friend class CActiveSchedulerWait;
public:
struct TLoop;
typedef TLoop* TLoopOwner;
public:
IMPORT_C CActiveScheduler();
IMPORT_C ~CActiveScheduler();
IMPORT_C static void Install(CActiveScheduler* aScheduler);
IMPORT_C static CActiveScheduler* Current();
IMPORT_C static void Add(CActive* aActive);
IMPORT_C static void Start();
IMPORT_C static void Stop();
IMPORT_C static TBool RunIfReady(TInt& aError, TInt aMinimumPriority);
IMPORT_C static CActiveScheduler* Replace(CActiveScheduler* aNewActiveScheduler);
IMPORT_C virtual void WaitForAnyRequest();
IMPORT_C virtual void Error(TInt aError) const;
IMPORT_C void Halt(TInt aExitCode) const;
IMPORT_C TInt StackDepth() const;
private:
static void Start(TLoopOwner* aOwner);
IMPORT_C virtual void OnStarting();
IMPORT_C virtual void OnStopping();
IMPORT_C virtual void Reserved_1();
IMPORT_C virtual void Reserved_2();
void Run(TLoopOwner* const volatile& aLoop);
void DoRunL(TLoopOwner* const volatile& aLoop, CActive* volatile & aCurrentObj);
friend class CPrivatePolledActiveScheduler; // added
protected:
IMPORT_C virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1);
protected:
inline TInt Level() const {return StackDepth();} // deprecated
private:
TLoop* iStack;
TPriQue<CActive> iActiveQ;
TAny* iSpare;
};
class TCleanupItem;
class CleanupStack
{
public:
IMPORT_C static void PushL(TAny* aPtr);
IMPORT_C static void PushL(CBase* aPtr);
IMPORT_C static void PushL(TCleanupItem anItem);
IMPORT_C static void Pop();
IMPORT_C static void Pop(TInt aCount);
IMPORT_C static void PopAndDestroy();
IMPORT_C static void PopAndDestroy(TInt aCount);
IMPORT_C static void Check(TAny* aExpectedItem);
inline static void Pop(TAny* aExpectedItem);
inline static void Pop(TInt aCount, TAny* aLastExpectedItem);
inline static void PopAndDestroy(TAny* aExpectedItem);
inline static void PopAndDestroy(TInt aCount, TAny* aLastExpectedItem);
};
/*
* This will declare CPrivatePolledActiveScheduler as a friend
* of all classes that define a friend. CPrivatePolledActiveScheduler needs to
* be a friend of CActive
*/
//#define friend friend class CPrivatePolledActiveScheduler; friend
/*
* This will change the:
* void DoStart();
* method in CActiveScheduler to:
* void DoStart(); friend class CPrivatePolledActiveScheduler;
* We need this to access the private datamembers in CActiveScheduler.
*/
//#define DoStart() DoStart(); friend class CPrivatePolledActiveScheduler;
//#include <e32base.h>
#include "PolledAS.h"
class CPrivatePolledActiveScheduler : public CActiveScheduler
{
public:
void Schedule();
};
void CPrivatePolledActiveScheduler::Schedule()
{
TDblQueIter<CActive> q(iActiveQ);
q.SetToFirst();
FOREVER
{
CActive *pR=q++;
if (pR)
{
//TRequestStatus::EActive = 1, //bit0
//TRequestStatus::ERequestPending = 2, //bit1
if (pR->IsActive() && pR->iStatus!=KRequestPending)
{
// pR->iActive=EFalse; // won't this cause trouble?
pR->iStatus.iFlags&=~TRequestStatusFaked::EActive;
//debugPrintFile(_L("as: %08x"), pR);
TRAPD(r,pR->RunL());
//pR->iStatus=TRequestStatus::ERequestPending;
break;
}
}
else
break;
}
}
static CPolledActiveScheduler* sPolledActiveScheduler = NULL;
CPolledActiveScheduler::~CPolledActiveScheduler()
{
sPolledActiveScheduler = NULL;
delete iPrivatePolledActiveScheduler;
}
CPolledActiveScheduler* CPolledActiveScheduler::NewL()
{
// if (sPolledActiveScheduler == NULL)
{
sPolledActiveScheduler = new(ELeave)CPolledActiveScheduler;
CleanupStack::PushL(sPolledActiveScheduler);
sPolledActiveScheduler->ConstructL();
CleanupStack::Pop();
}
return sPolledActiveScheduler;
}
void CPolledActiveScheduler::ConstructL()
{
iPrivatePolledActiveScheduler = new(ELeave) CPrivatePolledActiveScheduler;
iPrivatePolledActiveScheduler->Install(iPrivatePolledActiveScheduler);
}
void CPolledActiveScheduler::Schedule()
{
iPrivatePolledActiveScheduler->Schedule();
}
CPolledActiveScheduler* CPolledActiveScheduler::Instance()
{
// return (CPolledActiveScheduler*) CActiveScheduler::Current();
return sPolledActiveScheduler;
}

View file

@ -1,628 +0,0 @@
// EmuScan routines for Pico, also simple text and shape drawing routines.
// (c) Copyright 2006, notaz
// All Rights Reserved
#include "vid.h"
#include "../Engine.h"
#include <pico/pico_int.h>
#include "../../common/emu.h"
#include "blit.h"
#include "debug.h"
// global stuff
extern TPicoAreaConfigEntry areaConfig[];
extern const char *actionNames[];
// main framebuffer
static void *screenbuff = 0; // pointer to real device video memory
//static
extern "C" { unsigned char *PicoDraw2FB = 0; } // temporary buffer
const int framebuffsize = (8+320)*(8+240+8)*2+8*2; // PicoDraw2FB size (in bytes+to support new rendering mode)
// drawer function pointers
static void (*drawTextFps)(const char *text) = 0;
static void (*drawTextNotice)(const char *text) = 0;
// blitter
static void (*vidBlit)(int full) = 0;
// colors
const unsigned short color_red = 0x022F;
const unsigned short color_red_dim = 0x0004;
const unsigned short color_green = 0x01F1;
const unsigned short color_blue = 0x0F11;
const unsigned short color_grey = 0x0222;
// other
int txtheight_fit = 138;
// bitmasks
static const unsigned long mask_numbers[] = {
0x12244800, // 47 2F /
0x69999600, // 48 30 0
0x26222200, // 49 31 1
0x69168F00, // 50 32 2
0x69219600, // 51 33 3
0x266AF200, // 52 34 4
0xF8E11E00, // 53 35 5
0x68E99600, // 54 36 6
0x71222200, // 55 37 7
0x69699600, // 56 38 8
0x69719600, // 57 39 9
0x04004000, // 58 3A :
0x04004400, // 59 3B ;
0x01242100, // 60 3C <
0x00707000, // 61 3D =
0x04212400, // 62 3E >
0x69240400, // 63 3F ?
0x00000000, // 64 40 @ [used instead of space for now]
0x22579900, // 65 41 A
0xE9E99E00, // 66 42 B
0x69889600, // 67 43 C
0xE9999E00, // 68 44 D
0xF8E88F00, // 69 45 E
0xF8E88800, // 70 46 F
0x698B9700, // 71 47 G
0x99F99900, // 72 48 H
0x44444400, // 73 49 I
0x11119600, // 74 4A J
0x9ACCA900, // 75 4B K
0x88888F00, // 76 4C L
0x9F999900, // 77 4D M
0x9DDBB900, // 78 4E N
0x69999600, // 79 4F O
0xE99E8800, // 80 50 P
0x6999A500, // 81 51 Q
0xE99E9900, // 82 52 R
0x69429600, // 83 53 S
0x72222200, // 84 54 T
0x99999600, // 85 55 U
0x55552200, // 86 56 V
0x9999F900, // 87 57 W
0x55225500, // 88 58 X
0x55222200, // 89 59 Y
0xF1248F00, // 90 5A Z
};
////////////////////////////////
// PicoScan functions
static int EmuScanBegin8(unsigned int num)
{
DrawLineDest = PicoDraw2FB + 328*num + 8;
return 0;
}
static int EmuScanEndFit0(unsigned int num)
{
// 0.75, 168 lines
static int u = 0, num2 = 0;
if(!num) u = num2 = 0;
DrawLineDest = PicoDraw2FB + 328*(++num2) + 8;
u += 6666;
if(u < 10000) {
// u += 7500;
return 1;
}
u -= 10000;
return 0;
}
////////////////////////////////
// text drawers
// warning: text must be at least 1px away from screen borders
static void drawTextM2(int x, int y, const char *text)
{
unsigned char *vidmem = PicoDraw2FB + 328*8 + 8;
int charmask, i, cx = x, cy;
unsigned char *l, *le;
// darken the background (left border)
for(l=vidmem+(cx-1)+(y-1)*328, le=l+8*328; l < le; l+=328) *l = 0xE0;
for(const char *p=text; *p; p++) {
cy = y;
charmask = *(mask_numbers + (*p - 0x2F));
for(l = vidmem+cx+(y-1)*328, le = l+8*328; l < le; l+=328-4) {
*l = 0xE0; l++; *l = 0xE0; l++;
*l = 0xE0; l++; *l = 0xE0; l++;
*l = 0xE0;
}
for(i=0; i < 24; i++) {
if(charmask&0x80000000) *( vidmem + (cx+(i&3)) + (cy+(i>>2))*328 ) = 0xf0;
charmask <<= 1;
}
cx += 5;
}
}
static void drawTextM2Fat(int x, int y, const char *text)
{
unsigned char *vidmem = PicoDraw2FB + 328*8 + 8;
int charmask, i, cx = x&~1, cy;
unsigned short *l, *le;
// darken the background (left border)
for(l=(unsigned short *)(vidmem+(cx-2)+(y-1)*328), le=l+8*328/2; l < le; l+=328/2) *l = 0xE0;
for(const char *p=text; *p; p++) {
cy = y;
for(l = (unsigned short *)(vidmem+cx+(y-1)*328), le = l+8*328/2; l < le; l+=328/2) {
l += 4;
*l-- = 0xe0e0; *l-- = 0xe0e0; *l-- = 0xe0e0; *l-- = 0xe0e0; *l = 0xe0e0;
}
charmask = *(mask_numbers + (*p - 0x2F));
for(i=0; i < 24; i++) {
if(charmask&0x80000000) *(unsigned short *)( vidmem + cx+(i&3)*2 + (cy+(i>>2))*328 ) = 0xf0f0;
charmask <<= 1;
}
cx += 5*2;
}
}
static void drawTextFpsCenter0(const char *text)
{
if(!text) return;
drawTextM2((Pico.video.reg[12]&1) ? 234 : 214, 216, text);
}
static void drawTextFpsFit0(const char *text)
{
if(!text) return;
drawTextM2Fat((Pico.video.reg[12]&1) ? 256-32 : 224-32, 160, text);
}
static void drawTextFpsFit2_0(const char *text)
{
if(!text) return;
drawTextM2Fat((Pico.video.reg[12]&1) ? 256-32 : 224-32, 216, text);
}
static void drawTextFps0(const char *text)
{
if(!text) return;
drawTextM2((Pico.video.reg[12]&1) ? 256 : 224, 216, text);
}
static void drawTextNoticeCenter0(const char *text)
{
if(!text) return;
drawTextM2(42, 216, text);
}
static void drawTextNoticeFit0(const char *text)
{
if(!text) return;
drawTextM2Fat(2, 160, text);
}
static void drawTextNoticeFit2_0(const char *text)
{
if(!text) return;
drawTextM2Fat(2, 216, text);
}
static void drawTextNotice0(const char *text)
{
if(!text) return;
drawTextM2(2, 216, text);
}
// -----------------------------------------------------------------
static int localPal[0x100];
static void fillLocalPal(void)
{
Pico.m.dirtyPal = 0;
if (PicoOpt&0x10) {
// 8bit fast renderer
vidConvCpyRGB32(localPal, Pico.cram, 0x40);
return;
}
// 8bit accurate renderer
if(Pico.video.reg[0xC]&8) { // shadow/hilight mode
vidConvCpyRGB32(localPal, Pico.cram, 0x40);
vidConvCpyRGB32sh(localPal+0x40, Pico.cram, 0x40);
vidConvCpyRGB32hi(localPal+0x80, Pico.cram, 0x40);
memcpy32(localPal+0xc0, localPal+0x40, 0x40);
localPal[0xe0] = 0x00000000; // reserved pixels for OSD
localPal[0xf0] = 0x00ee0000;
}
else if (rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes
vidConvCpyRGB32(localPal, Pico.cram, 0x40);
vidConvCpyRGB32(localPal+0x40, HighPal, 0x40);
vidConvCpyRGB32(localPal+0x80, HighPal+0x40, 0x40);
} else {
vidConvCpyRGB32(localPal, Pico.cram, 0x40);
memcpy32(localPal+0x80, localPal, 0x40); // for sprite prio mess
}
}
// note: the internal 8 pixel border is taken care by asm code
static void vidBlit_90(int full)
{
unsigned char *ps = PicoDraw2FB+328*8;
unsigned long *pd = (unsigned long *) screenbuff;
if(Pico.video.reg[12]&1)
vidConvCpy_90(pd, ps, localPal, 320/8);
else {
if(full) vidClear(pd, 32);
pd += (240+VID_BORDER_R)*32;
vidConvCpy_90(pd, ps, localPal, 256/8);
if(full) vidClear(pd + (240+VID_BORDER_R)*256, 32);
}
}
static void vidBlit_270(int full)
{
unsigned char *ps = PicoDraw2FB+328*8;
unsigned long *pd = (unsigned long *) screenbuff;
if(Pico.video.reg[12]&1)
vidConvCpy_270(pd, ps, localPal, 320/8);
else {
if(full) vidClear(pd, 32);
pd += (240+VID_BORDER_R)*32;
ps -= 64; // the blitter starts copying from the right border, so we need to adjust
vidConvCpy_270(pd, ps, localPal, 256/8);
if(full) vidClear(pd + (240+VID_BORDER_R)*256, 32);
}
}
static void vidBlitCenter_0(int full)
{
unsigned char *ps = PicoDraw2FB+328*8+8;
unsigned long *pd = (unsigned long *) screenbuff;
if(Pico.video.reg[12]&1) ps += 32;
vidConvCpy_center_0(pd, ps, localPal);
if(full) vidClear(pd + (240+VID_BORDER_R)*224, 96);
}
static void vidBlitCenter_180(int full)
{
unsigned char *ps = PicoDraw2FB+328*8+8;
unsigned long *pd = (unsigned long *) screenbuff;
if(Pico.video.reg[12]&1) ps += 32;
vidConvCpy_center_180(pd, ps, localPal);
if(full) vidClear(pd + (240+VID_BORDER_R)*224, 96);
}
static void vidBlitFit_0(int full)
{
if(Pico.video.reg[12]&1)
vidConvCpy_center2_40c_0(screenbuff, PicoDraw2FB+328*8, localPal, 168);
else vidConvCpy_center2_32c_0(screenbuff, PicoDraw2FB+328*8, localPal, 168);
if(full) vidClear((unsigned long *)screenbuff + (240+VID_BORDER_R)*168, 320-168);
}
static void vidBlitFit_180(int full)
{
if(Pico.video.reg[12]&1)
vidConvCpy_center2_40c_180(screenbuff, PicoDraw2FB+328*8, localPal, 168);
else vidConvCpy_center2_32c_180(screenbuff, PicoDraw2FB+328*8-64, localPal, 168);
if(full) vidClear((unsigned long *)screenbuff + (240+VID_BORDER_R)*168, 320-168);
}
static void vidBlitFit2_0(int full)
{
if(Pico.video.reg[12]&1)
vidConvCpy_center2_40c_0(screenbuff, PicoDraw2FB+328*8, localPal, 224);
else vidConvCpy_center2_32c_0(screenbuff, PicoDraw2FB+328*8, localPal, 224);
if(full) vidClear((unsigned long *)screenbuff + (240+VID_BORDER_R)*224, 96);
}
static void vidBlitFit2_180(int full)
{
if(Pico.video.reg[12]&1)
vidConvCpy_center2_40c_180(screenbuff, PicoDraw2FB+328*8, localPal, 224);
else vidConvCpy_center2_32c_180(screenbuff, PicoDraw2FB+328*8-64, localPal, 224);
if(full) vidClear((unsigned long *)screenbuff + (240+VID_BORDER_R)*224, 96);
}
static void vidBlitCfg(void)
{
unsigned short *ps = (unsigned short *) PicoDraw2FB;
unsigned long *pd = (unsigned long *) screenbuff;
int i;
// hangs randomly (due to repeated ldms/stms?)
//for (int i = 1; i < 320; i++, ps += 240, pd += 256)
// vidConvCpyRGB32(pd, ps, 240);
for (i = 0; i < 320; i++, pd += VID_BORDER_R)
for (int u = 0; u < 240; u++, ps++, pd++)
*pd = ((*ps & 0xf) << 20) | ((*ps & 0xf0) << 8) | ((*ps & 0xf00) >> 4);
}
////////////////////////////////
// main functions
int vidInit(void *vidmem, int reinit)
{
if(!reinit) {
// prepare framebuffer
screenbuff = vidmem;
PicoDraw2FB = (unsigned char *) malloc(framebuffsize);
if(!screenbuff) return KErrNotSupported;
if(!PicoDraw2FB) return KErrNoMemory;
memset(PicoDraw2FB, 0, framebuffsize);
}
// select suitable blitters
vidBlit = vidBlit_270;
PicoScanBegin = EmuScanBegin8;
PicoScanEnd = NULL;
drawTextFps = drawTextFps0;
drawTextNotice = drawTextNotice0;
memset(localPal, 0, 0x100*4);
localPal[0xe0] = 0x00000000; // reserved pixels for OSD
localPal[0xf0] = 0x00ee0000;
// setup all orientation related stuff
if (currentConfig.rotation == TPicoConfig::PRot0)
{
if (currentConfig.scaling == TPicoConfig::PMCenter) {
vidBlit = vidBlitCenter_0;
drawTextFps = drawTextFpsCenter0;
drawTextNotice = drawTextNoticeCenter0;
} else if (currentConfig.scaling == TPicoConfig::PMFit2) {
vidBlit = vidBlitFit2_0;
drawTextFps = drawTextFpsFit2_0;
drawTextNotice = drawTextNoticeFit2_0;
} else {
vidBlit = vidBlitFit_0;
drawTextFps = drawTextFpsFit0;
drawTextNotice = drawTextNoticeFit0;
PicoScanBegin = NULL;
PicoScanEnd = EmuScanEndFit0;
}
} else if (currentConfig.rotation == TPicoConfig::PRot90) {
vidBlit = vidBlit_90;
}
else if (currentConfig.rotation == TPicoConfig::PRot180)
{
if (currentConfig.scaling == TPicoConfig::PMCenter)
{
vidBlit = vidBlitCenter_180;
drawTextFps = drawTextFpsCenter0;
drawTextNotice = drawTextNoticeCenter0;
}
else if (currentConfig.scaling == TPicoConfig::PMFit2) {
vidBlit = vidBlitFit2_180;
drawTextFps = drawTextFpsFit2_0;
drawTextNotice = drawTextNoticeFit2_0;
} else {
vidBlit = vidBlitFit_180;
drawTextFps = drawTextFpsFit0;
drawTextNotice = drawTextNoticeFit0;
PicoScanBegin = NULL;
PicoScanEnd = EmuScanEndFit0;
}
}
else if (currentConfig.rotation == TPicoConfig::PRot270) {
vidBlit = vidBlit_270;
}
fillLocalPal();
vidBlit(1);
PicoOpt |= 0x100;
Pico.m.dirtyPal = 1;
return 0;
}
void vidFree()
{
free(PicoDraw2FB);
PicoDraw2FB = 0;
}
void vidDrawFrame(char *noticeStr, char *fpsStr, int num)
{
DrawLineDest = PicoDraw2FB + 328*8 + 8;
// PicoFrame(); // moved to main loop
if (currentConfig.EmuOpt & EOPT_SHOW_FPS)
drawTextFps(fpsStr);
drawTextNotice(noticeStr);
if (Pico.m.dirtyPal) fillLocalPal();
vidBlit(!num); // copy full frame once a second
}
// -----------------------------------------------------------------
static void drawText0(int x, int y, const char *text, long color)
{
unsigned short *vidmem=(unsigned short *)PicoDraw2FB;
int charmask, i, cx = x, cy;
unsigned short *l, *le, dmask=0x0333;
// darken the background (left border)
for(l=vidmem+(cx-1)+(y-1)*240, le=vidmem+(cx-1)+(y+7)*240; l < le; l+=240)
*l = (*l >> 2) & dmask;
for(const char *p=text; *p; p++) {
cy = y;
charmask = *(mask_numbers + (*p - 0x2F));
for(l = vidmem+cx+(y-1)*240, le = vidmem+cx+(y+7)*240; l < le; l+=240-4) {
*l = (*l >> 2) & dmask; l++; *l = (*l >> 2) & dmask; l++;
*l = (*l >> 2) & dmask; l++; *l = (*l >> 2) & dmask; l++;
*l = (*l >> 2) & dmask;
}
for(i=0; i < 24; i++) {
// draw dot. Is this fast?
if(charmask&0x80000000) *( vidmem + (cx+(i&3)) + (cy+(i>>2))*240 ) = color;
charmask <<= 1;
}
cx += 5;
}
}
// draws rect with width - 1 and height - 1
static void drawRect(const TRect &rc, unsigned short color)
{
unsigned short *vidmem=(unsigned short *)PicoDraw2FB;
if(rc.iTl.iX - rc.iBr.iX && rc.iTl.iY - rc.iBr.iY) {
int stepX = rc.iTl.iX < rc.iBr.iX ? 1 : -1;
int stepY = rc.iTl.iY < rc.iBr.iY ? 1 : -1;
for(int x = rc.iTl.iX;; x += stepX) {
*(vidmem + rc.iTl.iY*240 + x) = *(vidmem + (rc.iBr.iY - stepY)*240 + x) = color;
if(x == rc.iBr.iX - stepX) break;
}
for(int y = rc.iTl.iY;; y += stepY) {
*(vidmem + y*240 + rc.iTl.iX) = *(vidmem + y*240 + rc.iBr.iX - stepX) = color;
if(y == rc.iBr.iY - stepY) break;
}
}
}
// draws fullsize filled rect
static void drawRectFilled(const TRect rc, unsigned short color)
{
unsigned short *vidmem=(unsigned short *)PicoDraw2FB;
if(rc.iTl.iX - rc.iBr.iX && rc.iTl.iY - rc.iBr.iY) {
int stepX = rc.iTl.iX < rc.iBr.iX ? 1 : -1;
int stepY = rc.iTl.iY < rc.iBr.iY ? 1 : -1;
for(int y = rc.iTl.iY;; y += stepY) {
for(int x = rc.iTl.iX;; x += stepX) {
*(vidmem + y*240 + x) = *(vidmem + y*240 + x) = color;
if(x == rc.iBr.iX) break;
}
if(y == rc.iBr.iY) break;
}
}
}
// direction: -1 left, 1 right
static void drawArrow0(TPoint p, int direction, unsigned short color)
{
unsigned short *vidmem=(unsigned short *)PicoDraw2FB;
int width = 15;
int x = p.iX;
int y = p.iY;
for(; width > 0; x+=direction, y++, width -=2)
for(int i=0; i < width; i++)
*(vidmem + x + y*240 + i*240) = color;
}
static char *vidGetScanName(int scan)
{
static char buff[32];
if((scan >= '0' && scan <= '9') || (scan >= 'A' && scan <= 'Z')) {
buff[0] = (char) scan; buff[1] = 0;
} else {
switch(scan) {
case 0x01: strcpy(buff, "BSPACE"); break;
case 0x03: strcpy(buff, "OK"); break;
case 0x05: strcpy(buff, "SPACE"); break;
case 0x0e: strcpy(buff, "AST"); break;
case 0x0f: strcpy(buff, "HASH"); break;
case 0x12: strcpy(buff, "SHIFT"); break;
case 0x19: strcpy(buff, "ALT"); break;
case 0x79: strcpy(buff, "PLUS"); break;
case 0x7a: strcpy(buff, "DOT"); break;
case 0xa5: strcpy(buff, "JOG@UP"); break;
case 0xa6: strcpy(buff, "JOG@DOWN"); break;
case 0xb5: strcpy(buff, "INET"); break;
case 0xd4: strcpy(buff, "JOG@PUSH"); break;
case 0xd5: strcpy(buff, "BACK"); break;
default: sprintf(buff, "KEY@%02X", scan); break;
}
}
return buff;
}
void vidKeyConfigFrame(const TUint whichAction)
{
int i;
char buttonNames[128];
buttonNames[0] = 0;
memset(PicoDraw2FB, 0, framebuffsize);
unsigned long currentActCode = 1 << whichAction;
// draw all "buttons" in reverse order
const TPicoAreaConfigEntry *e = areaConfig + 1; i = 0;
while(e->rect != TRect(0,0,0,0)) { e++; i++; }
for(e--, i--; e->rect != TRect(0,0,0,0); e--, i--)
drawRect(e->rect, (currentConfig.KeyBinds[i+256] & currentActCode) ? color_red : color_red_dim);
// action name control
drawRectFilled(TRect(72, 2, 168, 20), color_grey); // 96x14
drawArrow0(TPoint(80, 3), -1, color_green);
drawArrow0(TPoint(160, 3), 1, color_green);
drawText0(86, 9, actionNames[whichAction], color_red);
// draw active button names if there are any
for (i = 0; i < 256; i++) {
if (currentConfig.KeyBinds[i] & currentActCode) {
if(buttonNames[0]) strcat(buttonNames, ";@");
strcat(buttonNames, vidGetScanName(i));
}
}
if (buttonNames[0]) {
buttonNames[61] = 0; // only 60 chars fit
drawText0(6, 48, buttonNames, color_blue);
}
vidBlitCfg();
}
void vidDrawNotice(const char *txt)
{
if(PicoDraw2FB) {
drawTextNotice(txt);
vidBlit(1);
}
}

View file

@ -1,9 +0,0 @@
#include <e32base.h>
// let's do it in more c-like way
int vidInit(void *vidmem, int reinit);
void vidFree();
void vidDrawFrame(char *noticeStr, char *fpsStr, int num);
void vidKeyConfigFrame(const TUint whichAction);
void vidDrawFCconfigDone();
void vidDrawNotice(const char *txt); // safe to call anytime, draws text for 1 frame

View file

@ -1,86 +0,0 @@
enum TAppMenuCommands
{
// Emu menu
EEikCmdPicoMain = 10000,
EEikCmdPicoResume,
EEikCmdPicoLoadState,
EEikCmdPicoSaveState,
EEikCmdPicoLoadROM,
EEikCmdPicoReset,
EEikCmdPicoConfig,
EEikCmdPicoKeys,
EEikCmdPicoSettings,
// Frameskip submenu
EEikCmdPicoFrameskip,
EEikCmdPicoFrameskipAuto,
EEikCmdPicoFrameskip0,
EEikCmdPicoFrameskip1,
EEikCmdPicoFrameskip2,
EEikCmdPicoFrameskip4,
EEikCmdPicoFrameskip8,
// Debug menu
EEikCmdPicoDebug,
// EEikCmdPicoDebugKillEmu,
EEikCmdPicoDebugInfo,
// config Dialog
ECtlOptDone,
// pages
ECtlOptPageMain,
ECtlOptPageSound,
ECtlOptPageMCD,
ECtlOptPageMisc,
// main page
ECtlOptRotationLabel,
ECtlOptRotation,
ECtlOptRotation0,
ECtlOptRotation90,
ECtlOptRotation180,
ECtlOptRotation270,
ECtlOptScreenModeLabel,
ECtlOptScreenMode,
ECtlOptScreenModeCenter,
ECtlOptScreenModeFit,
ECtlOptScreenModeFit2,
ECtlOptUseAltRend,
// ECtlOptUseAccTiming,
// ECtlOptUseAccSprites,
ECtlOptShowFPS,
// sound page
ECtlOptEnableSound,
ECtlOptChipSelLabel,
ECtlOptEmulateZ80,
ECtlOptEmulateYM2612,
ECtlOptEmulateSN76496,
ECtlOptSndQLabel,
ECtlOptSndQuality,
// MCD page
ECtlOptCDleds,
ECtlOptCDcdda,
ECtlOptCDpcm,
ECtlOptCDramcart,
ECtlOptCDscalerot,
ECtlOptCDbettersync,
// misc page
ECtlOpt6ButtonPad,
ECtlOptGzipStates,
ECtlOptUseSRAM,
ECtlOptMotDontUseVol,
ECtlOptRegion,
// about dialog
EEikCmdPicoAboutDoneCmd,
EEikCmdPicoAboutCreditsCmd,
ECtlPicoAboutText,
// credits
ECtlPicoCreditsText,
// debug
ECtlDebugEdit
};
#define ECtlAboutVersion 1
#define ECtlAboutLinks 2

View file

@ -1,9 +0,0 @@
%{"notaz"}
:"notaz"
#{"PicoDrive"}, (0xA00010F3), 1, 51, 1, TYPE=SA
(0x101F6300), 3, 0, 0, {"UIQ30ProductID"}
"picodrive.exe"-"!:\sys\bin\PicoDrive.exe"
"rsc/picodrive.rsc"-"!:\resource\apps\PicoDrive.rsc"
"picodrive.mbm"-"!:\resource\apps\PicoDrive.mbm"
"rsc/picodrive_loc.rsc"-"!:\resource\apps\PicoDrive_loc.rsc"
"rsc/picodrive_reg.rsc"-"!:\private\10003a3f\import\apps\PicoDrive_reg.rsc"

View file

@ -1,33 +0,0 @@
// port specific settings
#ifndef PORT_CONFIG_H
#define PORT_CONFIG_H
#define CASE_SENSITIVE_FS 0
#define DONT_OPEN_MANY_FILES 0
#define REDUCE_IO_CALLS 0
#define SIMPLE_WRITE_SOUND 0
// draw2.c
#define START_ROW 0 // which row of tiles to start rendering at?
#define END_ROW 28 // ..end
// pico.c
#define CAN_HANDLE_240_LINES 0 // for now
// logging emu events
#define EL_LOGMASK (EL_STATUS) // |EL_SVP|EL_ANOMALY)
//extern void dprintf(char *format, ...);
//#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)
#define dprintf(x...)
// platform
#define PATH_SEP "\\"
#define PATH_SEP_C '\\'
#define MENU_X2 0
// engine/vid.cpp, also update BORDER_R in port_config.s
#define VID_BORDER_R 16
#endif // PORT_CONFIG_H

Some files were not shown because too many files have changed in this diff Show more