LRESULT CALLBACK Instance::Global::Hooks::CBTProc(const int nCode,const WPARAM wParam,const LPARAM lParam)
		{
			NST_COMPILE_ASSERT( HCBT_CREATEWND >= 0 && HCBT_DESTROYWND >= 0 );

			switch (nCode)
			{
				case HCBT_CREATEWND:

					NST_ASSERT( lParam );

					if (const CREATESTRUCT* const createStruct = reinterpret_cast<const CBT_CREATEWND*>(lParam)->lpcs)
					{
						NST_VERIFY( wParam );
						global.hooks.OnCreate( *createStruct, reinterpret_cast<HWND>(wParam) );
					}

					return 0;

				case HCBT_DESTROYWND:

					NST_VERIFY( wParam );

					if (wParam)
						global.hooks.OnDestroy( reinterpret_cast<HWND>(wParam) );

					return 0;
			}

			return nCode < 0 ? ::CallNextHookEx( global.hooks.handle, nCode, wParam, lParam ) : 0;
		}
NES_POKE_AD(Fb,Wrk_7)
{
    NST_VERIFY( wrk.Writable(0) );

    if (wrk.Writable(0))
        wrk[0][address - 0x7000] = data;
}
		void Sound::Recorder::Flush(const Nes::Sound::Output& output)
		{
			if (recording)
			{
				NST_VERIFY( file.IsOpen() );

				try
				{
					for (uint i=0; i < 2; ++i)
						file.Write( output.samples[i], output.length[i] * waveFormat.nBlockAlign );
				}
				catch (Io::Wave::Exception ids)
				{
					recording = false;
					Window::User::Fail( ids );
					return;
				}

				size += output.length[0] + output.length[1];

				if (size >= nextBigSizeNotification)
				{
					nextBigSizeNotification += BIG_SIZE;
					Window::User::Inform( IDS_WAVE_WARN_FILE_BIG );
				}
				else if (size >= nextSmallSizeNotification)
				{
					Io::Screen() << Resource::String(IDS_SCREEN_SOUND_RECORDER_WRITTEN).Invoke( HeapString() << (nextSmallSizeNotification / ONE_MB) );
					nextSmallSizeNotification += SMALL_SIZE;
				}
			}
		}
				void Ks202::SubLoad(State::Loader& state,const dword baseChunk)
				{
					NST_VERIFY( (baseChunk == AsciiId<'K','0','2'>::V) );

					if (baseChunk == AsciiId<'K','0','2'>::V)
					{
						while (const dword chunk = state.Begin())
						{
							switch (chunk)
							{
								case AsciiId<'R','E','G'>::V:

									ctrl = state.Read8();
									break;

								case AsciiId<'I','R','Q'>::V:
								{
									State::Loader::Data<5> data( state );

									irq.unit.ctrl = data[0];
									irq.unit.count = data[1] | data[2] << 8;
									irq.unit.latch = data[3] | data[4] << 8;
									irq.Connect( data[0] & 0xF );

									break;
								}
							}

							state.End();
						}
					}
				}
Beispiel #5
0
			void Loader::Uncompress(byte* const data,const dword length)
			{
				NST_VERIFY( length );

				switch (Read8())
				{
					case NO_COMPRESSION:

						Read( data, length );
						break;

					case ZLIB_COMPRESSION:

						if (!Zlib::AVAILABLE)
						{
							throw RESULT_ERR_UNSUPPORTED;
						}
						else if (chunks.Back())
						{
							Vector<byte> buffer( chunks.Back() );
							Read( buffer.Begin(), buffer.Size() );

							if (Zlib::Uncompress( buffer.Begin(), buffer.Size(), data, length ))
								break;
						}

					default:

						throw RESULT_ERR_CORRUPT_FILE;
				}
			}
Beispiel #6
0
		Result Fds::InsertDisk(uint disk,const uint side)
		{
			NST_VERIFY( disks.sides.count );

			if (side < 2)
			{
				disk = (disk * 2) + side;

				if (disk < disks.sides.count)
				{
					if (disks.current != disk)
					{
						const uint prev = disks.current;

						disks.current = disk;
						disks.mounting = Disks::MOUNTING;

						adapter.Mount( NULL );

						if (prev != Disks::EJECTED)
							Api::Fds::diskCallback( Api::Fds::DISK_EJECT, prev / 2, prev % 2 );

						Api::Fds::diskCallback( Api::Fds::DISK_INSERT, disk / 2, disk % 2 );

						return RESULT_OK;
					}

					return RESULT_NOP;
				}
			}

			return RESULT_ERR_INVALID_PARAM;
		}
Beispiel #7
0
		Result Tracker::TryResync(Result lastResult,bool excludeFrame) const
		{
			NST_VERIFY( NES_SUCCEEDED(lastResult) );

			if (NES_SUCCEEDED(lastResult) && lastResult != RESULT_NOP)
				Resync( excludeFrame );

			return lastResult;
		}
		Point::Client::Client(HWND const hWnd)
		{
			RECT tmp;
			::GetClientRect( hWnd, &tmp );
			NST_VERIFY( !tmp.left && !tmp.top );

			x = tmp.right;
			y = tmp.bottom;
		}
				void ResetBased4in1::SubLoad(State::Loader& state,const dword baseChunk)
				{
					NST_VERIFY( baseChunk == (AsciiId<'B','R','4'>::V) );

					if (baseChunk == AsciiId<'B','R','4'>::V)
					{
						while (const dword chunk = state.Begin())
						{
							if (chunk == AsciiId<'R','E','G'>::V)
								resetSwitch = state.Read8() & 0x3;

							state.End();
						}
					}
				}
				void Tc0190fmcPal16r4::SubLoad(State::Loader& state,const dword baseChunk)
				{
					NST_VERIFY( baseChunk == (AsciiId<'T','T','C'>::V) );

					if (baseChunk == AsciiId<'T','T','C'>::V)
					{
						while (const dword chunk = state.Begin())
						{
							if (chunk == AsciiId<'I','R','Q'>::V)
								irq.unit.LoadState( state );

							state.End();
						}
					}
				}
			uint LightGun::Poll()
			{
				if (input)
				{
					Controllers::Zapper& zapper = input->zapper;
					input = NULL;

					if (Controllers::Zapper::callback( zapper ))
					{
						fire = (zapper.fire ? arcade ? 0x80 : 0x10 : 0x00);

						if (zapper.y < Video::Screen::HEIGHT && zapper.x < Video::Screen::WIDTH)
							pos = zapper.y * Video::Screen::WIDTH + zapper.x;
						else
							pos = ~0U;
					}
				}

				if (pos < Video::Screen::WIDTH * Video::Screen::HEIGHT)
				{
					ppu.Update();

					uint pixel = ppu.GetPixelCycles();

					if (pos < pixel && pos >= pixel - PHOSPHOR_DECAY)
					{
						pixel = ppu.GetPixel( pos );

						if (arcade)
						{
							NST_COMPILE_ASSERT( LIGHT_SENSOR >= 0x3F );
							NST_VERIFY( pixel <= 0x3F );

							if (pixel > 0x3F)
								return pixel;

							pixel = ppu.GetYuvColor( pixel );
						}

						return lightMap[pixel];
					}
				}

				return 0;
			}
		Point::Picture::Picture(HWND const hWnd)
		{
			RECT tmp;
			::GetClientRect( hWnd, &tmp );
			NST_VERIFY( !tmp.left && !tmp.top );

			for (HWND hChild = ::GetTopWindow(hWnd); hChild; hChild = ::GetNextWindow(hChild,GW_HWNDNEXT))
			{
				RECT rChild;
				::GetClientRect( hChild, &rChild );
				tmp.bottom -= rChild.bottom - rChild.top;
			}

			if (tmp.bottom < 0)
				tmp.bottom = 0;

			x = tmp.right;
			y = tmp.bottom;
		}
Beispiel #13
0
				void Standard::SubLoad(State::Loader& state,const dword baseChunk)
				{
					NST_VERIFY( baseChunk == (AsciiId<'F','D','A'>::V) );

					if (baseChunk == AsciiId<'F','D','A'>::V)
					{
						while (const dword chunk = state.Begin())
						{
							if (chunk == AsciiId<'I','R','Q'>::V)
							{
								State::Loader::Data<3> data( state );

								irq.unit.enabled = data[0] & 0x1;
								irq.unit.latch = data[1];
								irq.unit.count = data[2];
							}

							state.End();
						}
					}
				}
			dword ReadRom(const uint type,const uint index,dword length,Context::Rom* const roms)
			{
				NST_ASSERT( type < 2 && index < 16 );

				Log() << "Unif: "
                      << (type ? "CHR-ROM " : "PRG-ROM ")
                      << char(index < 10 ? index + '0' : index-10 + 'A')
                      << " size: "
                      << (length / SIZE_1K)
                      << "k" NST_LINEBREAK;

				dword available = 0;

				for (uint i=0; i < 16; ++i)
					available += roms[i].data.Size();

				available = MAX_ROM_SIZE - available;
				NST_VERIFY( length <= available );

				if (length > available)
				{
					roms[index].truncated = length - available;
					length = available;

					Log() << "Unif: warning, "
                          << (type ? "CHR-ROM " : "PRG-ROM ")
                          << char(index < 10 ? index + '0' : index-10 + 'A')
                          << " truncated to: "
                          << (length / SIZE_1K)
                          << "k" NST_LINEBREAK;
				}

				if (length)
				{
					roms[index].data.Set( length );
					stream.Read( roms[index].data.Mem(), length );
				}

				return length;
			}
			void ReadHeader()
			{
				if (stream.Read32() != AsciiId<'U','N','I','F'>::V)
					throw RESULT_ERR_INVALID_FILE;

				dword version = stream.Read32();

				Log() << "Unif: revision " << version << NST_LINEBREAK;

				byte reserved[HEADER_RESERVED_LENGTH];
				stream.Read( reserved );

				for (uint i=0; i < HEADER_RESERVED_LENGTH; ++i)
				{
					NST_VERIFY( !reserved[i] );

					if (reserved[i])
					{
						Log() << "Unif: warning, unknown header data" NST_LINEBREAK;
						break;
					}
				}
			}
Beispiel #16
0
			Saver& Saver::Compress(const byte* const data,const dword length)
			{
				NST_VERIFY( length );

				if (Zlib::AVAILABLE && useCompression && length > 1)
				{
					Vector<byte> buffer( length - 1 );

					if (const dword compressed = Zlib::Compress( data, length, buffer.Begin(), buffer.Size(), Zlib::BEST_COMPRESSION ))
					{
						chunks.Back() += 1 + compressed;
						stream.Write8( ZLIB_COMPRESSION );
						stream.Write( buffer.Begin(), compressed );
						return *this;
					}
				}

				chunks.Back() += 1 + length;
				stream.Write8( NO_COMPRESSION );
				stream.Write( data, length );

				return *this;
			}
Beispiel #17
0
		void Cartridge::LoadState(State::Loader& state)
		{
			while (const dword chunk = state.Begin())
			{
				switch (chunk)
				{
					case AsciiId<'M','P','R'>::V:

						board->LoadState( state );
						break;

					case AsciiId<'V','S','S'>::V:

						NST_VERIFY( vs );

						if (vs)
							vs->LoadState( state );

						break;
				}

				state.End();
			}
		}
		Instance::Events::Callbacks::~Callbacks()
		{
			NST_VERIFY( Empty() );
		}
			void ReadChunks()
			{
				Context context;

				while (!stream.Eof())
				{
					dword id = stream.Read32();
					const dword length = stream.Read32();
					NST_VERIFY( length <= SIZE_1K * 4096UL );

					switch (id)
					{
						case AsciiId<'N','A','M','E'>::V: id = (context( 0, id ) ? ReadName       (         ) : 0); break;
						case AsciiId<'R','E','A','D'>::V: id = (context( 1, id ) ? ReadComment    (         ) : 0); break;
						case AsciiId<'D','I','N','F'>::V: id = (context( 2, id ) ? ReadDumper     (         ) : 0); break;
						case AsciiId<'T','V','C','I'>::V: id = (context( 3, id ) ? ReadSystem     ( context ) : 0); break;
						case AsciiId<'B','A','T','R'>::V: id = (context( 4, id ) ? ReadBattery    (         ) : 0); break;
						case AsciiId<'M','A','P','R'>::V: id = (context( 5, id ) ? ReadBoard      (         ) : 0); break;
						case AsciiId<'M','I','R','R'>::V: id = (context( 6, id ) ? ReadMirroring  (         ) : 0); break;
						case AsciiId<'C','T','R','L'>::V: id = (context( 7, id ) ? ReadController (         ) : 0); break;
						case AsciiId<'V','R','O','R'>::V: id = (context( 8, id ) ? ReadChrRam     (         ) : 0); break;

						default: switch (id & 0x00FFFFFF)
						{
							case AsciiId<'P','C','K'>::V:
							case AsciiId<'C','C','K'>::V:
							case AsciiId<'P','R','G'>::V:
							case AsciiId<'C','H','R'>::V:
							{
								uint index = id >> 24 & 0xFF;

								if (index >= Ascii<'0'>::V && index <= Ascii<'9'>::V)
								{
									index -= Ascii<'0'>::V;
								}
								else if (index >= Ascii<'A'>::V && index <= Ascii<'F'>::V)
								{
									index = index - Ascii<'A'>::V + 10;
								}
								else
								{
									index = ~0U;
								}

								if (index < 16)
								{
									switch (dword part = (id & 0x00FFFFFF))
									{
										case AsciiId<'P','C','K'>::V:
										case AsciiId<'C','C','K'>::V:

											part = (part == AsciiId<'C','C','K'>::V);
											id = (context( 9 + (part << 4) + index, id) ? ReadChecksum( part, index, context.roms[part][index] ) : 0);
											break;

										case AsciiId<'P','R','G'>::V:
										case AsciiId<'C','H','R'>::V:

											part = (part == AsciiId<'C','H','R'>::V);
											id = (context( 9 + 32 + (part << 4) + index, id ) ? ReadRom( part, index, length, context.roms[part] ) : 0);
											break;
									}

									break;
								}
							}

							default:

								id = ReadUnknown( id );
								break;
						}
					}

					if (id < length)
					{
						for (id = length - id; id > 0x7FFFFFFF; id -= 0x7FFFFFFF)
							stream.Seek( 0x7FFFFFFF );

						if (id)
							stream.Seek( id );
					}
					else if (id > length)
					{
						throw RESULT_ERR_CORRUPT_FILE;
					}
				}

				for (uint i=0; i < 2; ++i)
				{
					uint count = 0;
					dword size = 0;

					for (uint j=0; j < 16; ++j)
					{
						if (const dword n=context.roms[i][j].data.Size())
						{
							count++;
							size += n;
						}
					}

					if (count)
					{
						Profile::Board::Roms& rom = (i ? profile.board.chr : profile.board.prg);
						rom.resize( count );

						Ram& dst = (i ? chr : prg);
						dst.Set( size );

						if (!rom.empty())
						{
							for (Profile::Board::Pins::const_iterator it(rom.front().pins.begin()), end(rom.front().pins.end()); it != end; ++it)
								dst.Pin(it->number) = it->function.c_str();
						}

						size = 0;

						for (uint j=0, k=0; j < 16; ++j)
						{
							const Context::Rom& src = context.roms[i][j];

							if (src.data.Size())
							{
								rom[k].id = k;
								rom[k].size = src.data.Size();
								rom[k].hash.Assign( NULL, src.crc );
								k++;

								std::memcpy( dst.Mem(size), src.data.Mem(), src.data.Size() );
								size += src.data.Size();
							}
						}
					}
				}

				if (profileEx.nmt == ProfileEx::NMT_HORIZONTAL)
				{
					profile.board.solderPads = Profile::Board::SOLDERPAD_V;
				}
				else if (profileEx.nmt == ProfileEx::NMT_HORIZONTAL)
				{
					profile.board.solderPads = Profile::Board::SOLDERPAD_H;
				}

				switch (context.system)
				{
					case Context::SYSTEM_NTSC:

						if (favoredSystem == FAVORED_FAMICOM)
						{
							profile.system.type = Profile::System::FAMICOM;
						}
						if (favoredSystem == FAVORED_DENDY)
						{
							profile.system.type = Profile::System::DENDY;
							profile.system.cpu = Profile::System::CPU_DENDY;
							profile.system.ppu = Profile::System::PPU_DENDY;
						}
						else
						{
							profile.system.type = Profile::System::NES_NTSC;
						}
						break;

					default:

						profile.multiRegion = true;

						if (favoredSystem == FAVORED_FAMICOM)
						{
							profile.system.type = Profile::System::FAMICOM;
							break;
						}
						else if (favoredSystem != FAVORED_NES_PAL && favoredSystem != FAVORED_DENDY)
						{
							profile.system.type = Profile::System::NES_NTSC;
							break;
						}

					case Context::SYSTEM_PAL:

						if (favoredSystem == FAVORED_DENDY)
						{
							profile.system.type = Profile::System::DENDY;
							profile.system.cpu = Profile::System::CPU_DENDY;
							profile.system.ppu = Profile::System::PPU_DENDY;
						}
						else
						{
							profile.system.type = Profile::System::NES_PAL;
							profile.system.cpu = Profile::System::CPU_RP2A07;
							profile.system.ppu = Profile::System::PPU_RP2C07;
						}
						break;
				}
			}
			dword ReadController()
			{
				Log log;

				log << "Unif: controllers: ";

				const uint controller = stream.Read8();
				NST_VERIFY( !(controller & (0x40|0x80)) );

				if (controller & (0x1|0x2|0x4|0x8|0x10|0x20))
				{
					if (controller & 0x01)
					{
						profile.game.controllers[0] = Api::Input::PAD1;
						profile.game.controllers[1] = Api::Input::PAD2;

						log << "standard joypad";
					}

					if (controller & 0x02)
					{
						profile.game.controllers[1] = Api::Input::ZAPPER;

						cstring const zapper = ", zapper";
						log << (zapper + ((controller & 0x1) ? 0 : 2));
					}

					if (controller & 0x04)
					{
						profile.game.controllers[1] = Api::Input::ROB;

						cstring const rob = ", R.O.B.";
						log << (rob + ((controller & (0x1|0x2)) ? 0 : 2));
					}

					if (controller & 0x08)
					{
						profile.game.controllers[0] = Api::Input::PADDLE;

						cstring const paddle = ", paddle";
						log << (paddle + ((controller & (0x1|0x2|0x4)) ? 0 : 2));
					}

					if (controller & 0x10)
					{
						profile.game.controllers[1] = Api::Input::POWERPAD;

						cstring const powerpad = ", power pad";
						log << (powerpad + ((controller & (0x1|0x2|0x4|0x8)) ? 0 : 2));
					}

					if (controller & 0x20)
					{
						profile.game.controllers[2] = Api::Input::PAD3;
						profile.game.controllers[3] = Api::Input::PAD4;

						cstring const fourplayer = ", four player adapter";
						log << (fourplayer + ((controller & (0x1|0x2|0x4|0x8|0x10)) ? 0 : 2));
					}

					log << NST_LINEBREAK;
				}
				else
				{
					log << ((controller & (0x40|0x80)) ? "unknown" NST_LINEBREAK : "unspecified" NST_LINEBREAK);
				}

				return 1;
			}
			void TreeView::Item::Select() const
			{
				NST_VERIFY( hItem );
				TreeView_SelectItem( root, static_cast<HTREEITEM>(hItem) );
			}
			void TreeView::SetImageList(const ImageList& imageList) const
			{
				NST_VERIFY( imageList.handle );
				TreeView_SetImageList( control, static_cast<HIMAGELIST>(imageList.handle), TVSIL_NORMAL );
			}
Beispiel #23
0
			Loader::~Loader()
			{
				NST_VERIFY( chunks.Size() <= 1 );
			}
Beispiel #24
0
			Saver::~Saver()
			{
				NST_VERIFY( chunks.Size() == 1 );
			}