Skip to content

Commit

Permalink
Merge pull request #6 from fhoedemakers/develop
Browse files Browse the repository at this point in the history
Add menu and multiple game support
  • Loading branch information
fhoedemakers authored Apr 1, 2023
2 parents d075830 + fcf168d commit 3440fa1
Show file tree
Hide file tree
Showing 17 changed files with 33,962 additions and 33,053 deletions.
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ pico_sdk_init()

add_executable(PicoSystem_InfoNes
main.cpp
tar.cpp
menu.cpp
RomLister.cpp
assets/builtinrom.c
)

pico_set_program_name(PicoSystem_InfoNes "PicoSystem_InfoNes")
pico_set_program_version(PicoSystem_InfoNes "0.1")
pico_set_program_version(PicoSystem_InfoNes "v0.4-alpha")

pico_enable_stdio_uart(PicoSystem_InfoNes 1)
pico_enable_stdio_usb(PicoSystem_InfoNes 0)
Expand Down
55 changes: 38 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ Emulater is now bundled with the freeware homebrew game [Blade Buster](https://w

[A pre-release .uf2 binary to flash on your picosystem can be found here.](https://github.com/fhoedemakers/PicoSystem_InfoNes/releases)

Now you can play Nintendo NES games on the [Pimoroni PicoSystem](https://shop.pimoroni.com/products/picosystem) RP2040 gaming handheld.
Now you can store and play Nintendo multiple NES games on the [Pimoroni PicoSystem](https://shop.pimoroni.com/products/picosystem) RP2040 gaming handheld. A menu system is included for choosing your games to play.

![image](https://github.com/fhoedemakers/PicoSystem_InfoNes/blob/master/assets/PicoSystem.jpg)
(Note: Screenshots below do not represent the actual picture quality. The distortion is caused by the camera)
![image](assets/gamescreen.jpeg)

![image](assets/menuscreen.jpeg)

Click on image below to see a demo video.

Expand All @@ -19,31 +22,49 @@ Click on image below to see a demo video.

- Sound has to be implemented. Will be a challenge since the PicoSystem has as simple Piezo buzzer/speaker which has not the capabilities for generating proper sound from the NES.
- Code has to be cleaned up. Uses parts of the [PicoSystem library](https://github.com/pimoroni/picosystem).
- Companion App in Microsoft Windows for uploading roms to the handheld.
- Save game support.

## flashing the PicoSystem

## Uploading games and flashing the emulator
Since there is no SD card slot available, a companion app for Microsoft Windows is created that lets the user choose games and flash them to the Pico.
[More information here](https://github.com/fhoedemakers/PicoSystemInfoNesLoader). The app is included in the latest release.
The application also allows you to flash the emulator when not installed or a newer version is available. No more need for manually flashing.

![image](assets/Screen.png)

## Manually flashing the PicoSystem
- Download **PicoSystem_InfoNes.uf2** from the [releases page](https://github.com/fhoedemakers/PicoSystem_InfoNes/releases/latest).
- Connect PicoSystem using an USB-C cable to your computer. Make sure the PicoSystem is switched off.
- Push and hold the X button then the power-on button. Release the buttons and the drive RPI-RP2 appears on your computer.
- Drag and drop the UF2 file on to the RPI-RP2 drive. The PicoSystem will reboot and will now run the emulator.

## Manually uploading a game
Load single game rom by setting the device in BOOTSEL mode. (Connect to computer then Hold X and power on device)
The ROM should be placed at address **0x10110000**, and can be transferred using [picotool](https://github.com/raspberrypi/picotool).

```
picotool load rom.nes -t bin -o 0x10110000
```

**Attention: the upload address has been changed from 0x10080000 to 0x10110000.** This is because of the additional size of the built-in game baked into the executable.


## Button maps

- Y: SELECT on NES
- X: START on NES
- Y + X: Reset
- Y + LEFT: Start uploaded game
- Y + RIGHT: Start built-in freeware game [Blade Buster](https://www.rgcd.co.uk/2011/05/blade-buster-nes.html)
- Y: is mapped to NES Select
- X: is mapped to NES Start

### In-game
- Y + X: Open menu
- Y + LEFT: Previous game
- Y + RIGHT: Next Game
- Y + UP: Start built-in freeware game [Blade Buster](https://www.rgcd.co.uk/2011/05/blade-buster-nes.html)

### In-Menu
- Up/DOWN: Scroll through list
- A : Start selected game
- B : Exit menu

## Uploading game roms
Load roms by setting the device in BOOTSEL mode. (Connect to computer then Hold X and power on device)
The ROM should be placed at address **0x10090000**, and can be transferred using [picotool](https://github.com/raspberrypi/picotool).

```
picotool load rom.nes -t bin -o 0x10090000
```
**Attention: the upload address has been changed from 0x10080000 to 0x10090000.** This is because of the additional size of the built-in game baked into the executable.

## Screen Resolution
The original Nintendo Entertainment System has a resolution of 256x240 pixels. The PicoSystem has a resolution of 240x240 pixels. Therefore, on the PicoSystem the first and last 8 Pixels of each horizontal line are not visible.
Expand Down
51 changes: 51 additions & 0 deletions RomLister.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include <stdio.h>
#include <pico/stdlib.h>
#include <string.h>
#include "RomLister.h"
#include "FrensHelpers.h"
#include "tar.h"

inline bool checkNESMagic(const uint8_t *data);
// class to listing directories and .NES files
namespace Frens
{


// Buffer must have sufficient bytes to contain directory contents
RomLister::RomLister(uintptr_t NES_FILE_ADDR, void *buffer, size_t buffersize)
{
entries = (RomEntry *)buffer;
max_entries = buffersize / sizeof(RomEntry);
address = reinterpret_cast<const uint8_t *>(NES_FILE_ADDR);
numberOfEntries = 0;
}

RomLister::~RomLister()
{
}

RomLister::RomEntry *RomLister::GetEntries()
{
return entries;
}

char *RomLister::FolderName()
{
return directoryname;
}
size_t RomLister::Count()
{
return numberOfEntries;
}

void RomLister::list( )
{
numberOfEntries = GetValidTAREntries(address, checkNESMagic);
for ( int i=0; i< numberOfEntries; i++) {
entries[i].Index = i;
entries[i].IsDirectory = false;
strcpy(entries[i].Path, extractTAREntryatindex(i, address, checkNESMagic).filename.data());
}

}
}
36 changes: 36 additions & 0 deletions RomLister.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#ifndef ROMLISTER
#define ROMLISTER
#include <string>
#include <vector>
#include "rom_selector.h"
#define ROMLISTER_MAXPATH 100
namespace Frens {

class RomLister
{

public:
struct RomEntry {
char Path[ROMLISTER_MAXPATH]; // Without dirname
bool IsDirectory = false;
int Index = 0;
};
RomLister(uintptr_t NES_FILE_ADDR, void *buffer, size_t buffersize);
~RomLister();
RomEntry* GetEntries();
char *FolderName();
size_t Count();
void list( );

private:
char directoryname[ROMLISTER_MAXPATH];
int length{};
size_t max_entries{};
RomEntry *entries{};
size_t numberOfEntries{};
const uint8_t *address{};


};
}
#endif
Binary file added assets/Screen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 3440fa1

Please sign in to comment.