Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: rickyzhang82/nofrendo
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: moononournation/arduino-nofrendo
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref

Commits on Oct 21, 2020

  1. Copy the full SHA
    9f1c4e5 View commit details
  2. Copy the full SHA
    a1f20d4 View commit details
  3. vscode format

    moononournation committed Oct 21, 2020
    Copy the full SHA
    2151133 View commit details

Commits on Oct 22, 2020

  1. fix comment

    moononournation committed Oct 22, 2020
    Copy the full SHA
    4a0f720 View commit details
  2. fix strncmp length

    moononournation committed Oct 22, 2020
    Copy the full SHA
    0a9b8a9 View commit details
  3. relative include path

    moononournation committed Oct 22, 2020
    Copy the full SHA
    cceee7c View commit details
  4. mapper

    moononournation committed Oct 22, 2020
    Copy the full SHA
    567a0a5 View commit details
  5. nofrendo_log_print

    moononournation committed Oct 22, 2020
    Copy the full SHA
    8fdf1f8 View commit details
  6. nofrendo_log_print

    moononournation committed Oct 22, 2020
    Copy the full SHA
    73aa375 View commit details
  7. Copy the full SHA
    3fa1b37 View commit details
  8. nofrendo_main

    moononournation committed Oct 22, 2020
    Copy the full SHA
    80ba7ba View commit details
  9. Copy the full SHA
    5e8980c View commit details
  10. Copy the full SHA
    78c6a76 View commit details
  11. Copy the full SHA
    651ebda View commit details
  12. Copy the full SHA
    35673c5 View commit details
  13. Copy the full SHA
    4c1a834 View commit details
  14. Copy the full SHA
    4959458 View commit details
  15. Copy the full SHA
    d06c11c View commit details
  16. vscode format

    moononournation committed Oct 22, 2020
    Copy the full SHA
    ddb0d91 View commit details
  17. vscode format

    moononournation committed Oct 22, 2020
    Copy the full SHA
    c5718ff View commit details
  18. add maintainer

    moononournation committed Oct 22, 2020
    Copy the full SHA
    3df192d View commit details
  19. log _my_malloc

    moononournation committed Oct 22, 2020
    Copy the full SHA
    268310f View commit details
  20. #include "noftypes.h"

    moononournation committed Oct 22, 2020
    Copy the full SHA
    ea6cd94 View commit details
  21. Copy the full SHA
    42a0ed8 View commit details
  22. add paragraph and url

    moononournation committed Oct 22, 2020
    Copy the full SHA
    5ec5515 View commit details
  23. Create FUNDING.yml

    moononournation authored Oct 22, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    a20236a View commit details

Commits on Oct 23, 2020

  1. Copy the full SHA
    8b37604 View commit details
  2. Copy the full SHA
    14fbfcd View commit details

Commits on Oct 25, 2020

  1. Copy the full SHA
    9b3e29d View commit details
  2. bug fix

    moononournation committed Oct 25, 2020
    Copy the full SHA
    eb54774 View commit details

Commits on Oct 26, 2020

  1. Copy the full SHA
    0b0f1de View commit details
  2. Copy the full SHA
    d770af3 View commit details

Commits on Oct 27, 2020

  1. Copy the full SHA
    c395e88 View commit details
  2. Copy the full SHA
    21b6c73 View commit details

Commits on Oct 31, 2020

  1. Copy the full SHA
    a0fb8a3 View commit details
  2. display verbose error

    moononournation committed Oct 31, 2020
    Copy the full SHA
    cc20be4 View commit details

Commits on Nov 3, 2020

  1. Copy the full SHA
    b06ccaa View commit details

Commits on Nov 5, 2020

  1. Copy the full SHA
    3afcd67 View commit details

Commits on Nov 23, 2020

  1. Copy the full SHA
    616e4a1 View commit details

Commits on Dec 19, 2020

  1. Copy the full SHA
    93cc41c View commit details
  2. Copy the full SHA
    3132e41 View commit details
  3. minor reduce malloc

    moononournation committed Dec 19, 2020
    Copy the full SHA
    bccc04a View commit details

Commits on Dec 21, 2020

  1. Copy the full SHA
    58bed69 View commit details

Commits on Apr 4, 2021

  1. Copy the full SHA
    0239dbc View commit details

Commits on Jul 28, 2021

  1. add HX8357B defines

    moononournation committed Jul 28, 2021
    Copy the full SHA
    cafed82 View commit details
  2. add FatFS define

    moononournation committed Jul 28, 2021
    Copy the full SHA
    fd9f475 View commit details

Commits on Oct 17, 2021

  1. Copy the full SHA
    9c1d965 View commit details

Commits on Nov 29, 2022

  1. typo

    moononournation committed Nov 29, 2022
    Copy the full SHA
    2d24c6f View commit details

Commits on Feb 2, 2023

  1. add FUNDING.yml

    moononournation committed Feb 2, 2023
    Copy the full SHA
    301deee View commit details

Commits on Feb 23, 2024

  1. #6

    moononournation committed Feb 23, 2024
    Copy the full SHA
    c5ba6d3 View commit details
Showing with 30,874 additions and 34,650 deletions.
  1. +1 −0 .github/FUNDING.yml
  2. +0 −4 Makefile.am
  3. +0 −362 Makefile.in
  4. +13 −0 README.md
  5. +0 −168 acinclude.m4
  6. +0 −478 aclocal.m4
  7. +0 −973 config.guess
  8. +0 −11 config.h.in
  9. +0 −956 config.sub
  10. +0 −2,027 configure
  11. +0 −85 configure.in
  12. +0 −72 configure.in.in
  13. +287 −0 examples/esp32-nofrendo/controller.cpp
  14. BIN examples/esp32-nofrendo/data/Chase.nes
  15. +4 −0 examples/esp32-nofrendo/data/Chase.txt
  16. +197 −0 examples/esp32-nofrendo/display.cpp
  17. +92 −0 examples/esp32-nofrendo/esp32-nofrendo.ino
  18. +113 −0 examples/esp32-nofrendo/hw_config.h
  19. +261 −0 examples/esp32-nofrendo/osd.c
  20. +217 −0 examples/esp32-nofrendo/sound.c
  21. +0 −251 install-sh
  22. +7 −0 library.properties
  23. +0 −190 missing
  24. +0 −40 mkinstalldirs
  25. +0 −19 src/Makefile.am
  26. +0 −404 src/Makefile.in
  27. +0 −3 src/beos/Makefile.am
  28. +0 −300 src/beos/Makefile.in
  29. +0 −212 src/beos/osd.c
  30. +155 −154 src/bitmap.c
  31. +93 −93 src/bitmap.h
  32. +456 −465 src/config.c
  33. +0 −5 src/cpu/Makefile.am
  34. +0 −302 src/cpu/Makefile.in
  35. +1,326 −532 src/cpu/dis6502.c
  36. +59 −58 src/cpu/dis6502.h
  37. +2,556 −2,573 src/cpu/nes6502.c
  38. +176 −175 src/cpu/nes6502.h
  39. +635 −637 src/event.c
  40. +154 −154 src/event.h
  41. +697 −697 src/gui.c
  42. +145 −146 src/gui.h
  43. +390 −200 src/gui_elem.c
  44. +2 −2 src/gui_elem.h
  45. +4,533 −411 src/intro.c
  46. +53 −53 src/intro.h
  47. +0 −3 src/libsnss/Makefile.am
  48. +0 −300 src/libsnss/Makefile.in
  49. +847 −840 src/libsnss/libsnss.c
  50. +402 −397 src/libsnss/libsnss.h
  51. +187 −176 src/log.c
  52. +57 −57 src/log.h
  53. +0 −45 src/mappers/Makefile.am
  54. +0 −317 src/mappers/Makefile.in
  55. +63 −63 src/mappers/map000.c
  56. +240 −242 src/mappers/map001.c
  57. +93 −86 src/mappers/map002.c
  58. +85 −86 src/mappers/map003.c
  59. +273 −269 src/mappers/map004.c
  60. +324 −326 src/mappers/map005.c
  61. +98 −99 src/mappers/map007.c
  62. +93 −94 src/mappers/map008.c
  63. +198 −199 src/mappers/map009.c
  64. +160 −0 src/mappers/map010.c
  65. +92 −93 src/mappers/map011.c
  66. +143 −144 src/mappers/map015.c
  67. +190 −192 src/mappers/map016.c
  68. +270 −215 src/mappers/map018.c
  69. +168 −170 src/mappers/map019.c
  70. +233 −235 src/mappers/map024.c
  71. +120 −121 src/mappers/map032.c
  72. +143 −145 src/mappers/map033.c
  73. +99 −100 src/mappers/map034.c
  74. +162 −163 src/mappers/map040.c
  75. +168 −167 src/mappers/map041.c
  76. +195 −188 src/mappers/map042.c
  77. +151 −152 src/mappers/map046.c
  78. +198 −192 src/mappers/map050.c
  79. +233 −234 src/mappers/map064.c
  80. +143 −144 src/mappers/map065.c
  81. +92 −94 src/mappers/map066.c
  82. +114 −115 src/mappers/map070.c
  83. +181 −173 src/mappers/map073.c
  84. +129 −131 src/mappers/map075.c
  85. +110 −111 src/mappers/map078.c
  86. +90 −91 src/mappers/map079.c
  87. +230 −232 src/mappers/map085.c
  88. +86 −85 src/mappers/map087.c
  89. +76 −77 src/mappers/map093.c
  90. +86 −87 src/mappers/map094.c
  91. +90 −90 src/mappers/map099.c
  92. +139 −140 src/mappers/map160.c
  93. +115 −114 src/mappers/map229.c
  94. +94 −95 src/mappers/map231.c
  95. +515 −452 src/mappers/mapvrc.c
  96. +501 −499 src/memguard.c
  97. +93 −94 src/memguard.h
  98. +0 −12 src/nes/Makefile.am
  99. +0 −305 src/nes/Makefile.in
  100. +122 −122 src/nes/mmclist.c
  101. +49 −49 src/nes/mmclist.h
  102. +783 −770 src/nes/nes.c
  103. +214 −218 src/nes/nes.h
  104. +352 −353 src/nes/nes_mmc.c
  105. +144 −146 src/nes/nes_mmc.h
  106. +240 −211 src/nes/nes_pal.c
  107. +65 −65 src/nes/nes_pal.h
  108. +1,392 −1,402 src/nes/nes_ppu.c
  109. +239 −241 src/nes/nes_ppu.h
  110. +602 −601 src/nes/nes_rom.c
  111. +109 −110 src/nes/nes_rom.h
  112. +211 −212 src/nes/nesinput.c
  113. +103 −104 src/nes/nesinput.h
  114. +516 −517 src/nes/nesstate.c
  115. +63 −63 src/nes/nesstate.h
  116. +79 −77 src/nofconfig.h
  117. +401 −400 src/nofrendo.c
  118. +91 −89 src/nofrendo.h
  119. +119 −120 src/noftypes.h
  120. +190 −188 src/osd.h
  121. +139 −139 src/pcx.c
  122. +82 −82 src/pcx.h
  123. +0 −5 src/sdl/Makefile.am
  124. +0 −302 src/sdl/Makefile.in
  125. +0 −779 src/sdl/sdl.c
  126. +0 −8 src/sndhrdw/Makefile.am
  127. +0 −304 src/sndhrdw/Makefile.in
  128. +113 −115 src/sndhrdw/fds_snd.c
  129. +58 −59 src/sndhrdw/fds_snd.h
  130. +439 −447 src/sndhrdw/mmc5_snd.c
  131. +70 −70 src/sndhrdw/mmc5_snd.h
  132. +1,183 −1,195 src/sndhrdw/nes_apu.c
  133. +344 −349 src/sndhrdw/nes_apu.h
  134. +275 −278 src/sndhrdw/vrcvisnd.c
  135. +70 −70 src/sndhrdw/vrcvisnd.h
  136. +0 −5 src/unix/Makefile.am
  137. +0 −302 src/unix/Makefile.in
  138. +0 −309 src/unix/osd.c
  139. +65 −65 src/version.h
  140. +616 −574 src/vid_drv.c
  141. +145 −145 src/vid_drv.h
  142. +0 −3 src/win32/Makefile.am
  143. +0 −300 src/win32/Makefile.in
  144. +0 −224 src/win32/osd.c
  145. 0 stamp-h.in
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github: moononournation
4 changes: 0 additions & 4 deletions Makefile.am

This file was deleted.

362 changes: 0 additions & 362 deletions Makefile.in

This file was deleted.

13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# arduino-nofrendo

This is a special nofrendo version as a Arduino library.

## Implementation

Simple implement all function definded in osd.h to make it work.

Any Arduino platform that have enough processing power should work.

## Examples

- esp32-nofrendo.ino in examples folder is rewritten from https://github.com/espressif/esp32-nesemu.git
168 changes: 0 additions & 168 deletions acinclude.m4

This file was deleted.

478 changes: 0 additions & 478 deletions aclocal.m4

This file was deleted.

973 changes: 0 additions & 973 deletions config.guess

This file was deleted.

11 changes: 0 additions & 11 deletions config.h.in

This file was deleted.

956 changes: 0 additions & 956 deletions config.sub

This file was deleted.

2,027 changes: 0 additions & 2,027 deletions configure

This file was deleted.

85 changes: 0 additions & 85 deletions configure.in

This file was deleted.

72 changes: 0 additions & 72 deletions configure.in.in

This file was deleted.

287 changes: 287 additions & 0 deletions examples/esp32-nofrendo/controller.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
#include <Arduino.h>

#include "hw_config.h"

/* controller is GPIO */
#if defined(HW_CONTROLLER_GPIO)

extern "C" void controller_init()
{
#if defined(HW_CONTROLLER_GPIO_ANALOG_JOYSTICK)
pinMode(HW_CONTROLLER_GPIO_UP_DOWN, INPUT);
pinMode(HW_CONTROLLER_GPIO_LEFT_RIGHT, INPUT);
#else /* !defined(HW_CONTROLLER_GPIO_ANALOG_JOYSTICK) */
pinMode(HW_CONTROLLER_GPIO_UP, INPUT_PULLUP);
pinMode(HW_CONTROLLER_GPIO_DOWN, INPUT_PULLUP);
pinMode(HW_CONTROLLER_GPIO_LEFT, INPUT_PULLUP);
pinMode(HW_CONTROLLER_GPIO_RIGHT, INPUT_PULLUP);
#endif /* !defined(HW_CONTROLLER_GPIO_ANALOG_JOYSTICK) */
pinMode(HW_CONTROLLER_GPIO_SELECT, INPUT_PULLUP);
pinMode(HW_CONTROLLER_GPIO_START, INPUT_PULLUP);
pinMode(HW_CONTROLLER_GPIO_A, INPUT_PULLUP);
pinMode(HW_CONTROLLER_GPIO_B, INPUT_PULLUP);
pinMode(HW_CONTROLLER_GPIO_X, INPUT_PULLUP);
pinMode(HW_CONTROLLER_GPIO_Y, INPUT_PULLUP);
}

extern "C" uint32_t controller_read_input()
{
uint32_t u, d, l, r, s, t, a, b, x, y;

#if defined(HW_CONTROLLER_GPIO_ANALOG_JOYSTICK)

#if defined(HW_CONTROLLER_GPIO_REVERSE_UD)
int joyY = 4095 - analogRead(HW_CONTROLLER_GPIO_UP_DOWN);
#else /* !defined(HW_CONTROLLER_GPIO_REVERSE_UD) */
int joyY = analogRead(HW_CONTROLLER_GPIO_UP_DOWN);
#endif /* !defined(HW_CONTROLLER_GPIO_REVERSE_UD) */

#if defined(HW_CONTROLLER_GPIO_REVERSE_LF)
int joyX = 4095 - analogRead(HW_CONTROLLER_GPIO_LEFT_RIGHT);
#else /* !defined(HW_CONTROLLER_GPIO_REVERSE_LF) */
int joyX = analogRead(HW_CONTROLLER_GPIO_LEFT_RIGHT);
#endif /* !defined(HW_CONTROLLER_GPIO_REVERSE_LF) */

// Serial.printf("joyX: %d, joyY: %d\n", joyX, joyY);
#if defined(ARDUINO_ODROID_ESP32)

if (joyY > 2048 + 1024)
{
u = 0;
d = 1;
}
else if (joyY > 1024)
{
u = 1;
d = 0;
}
else
{
u = 1;
d = 1;
}
if (joyX > 2048 + 1024)
{
l = 0;
r = 1;
}
else if (joyX > 1024)
{
l = 1;
r = 0;
}
else
{
l = 1;
r = 1;
}

#else /* !defined(ARDUINO_ODROID_ESP32) */

if (joyY > 2048 + 1024)
{
u = 1;
d = 0;
}
else if (joyY < 1024)
{
u = 0;
d = 1;
}
else
{
u = 1;
d = 1;
}

if (joyX > 2048 + 1024)
{
l = 1;
r = 0;
}
else if (joyX < 1024)
{
l = 0;
r = 1;
}
else
{
l = 1;
r = 1;
}

#endif /* !defined(ARDUINO_ODROID_ESP32) */
#else /* !defined(HW_CONTROLLER_GPIO_ANALOG_JOYSTICK) */
u = digitalRead(HW_CONTROLLER_GPIO_UP);
d = digitalRead(HW_CONTROLLER_GPIO_DOWN);
l = digitalRead(HW_CONTROLLER_GPIO_LEFT);
r = digitalRead(HW_CONTROLLER_GPIO_RIGHT);
#endif /* !defined(HW_CONTROLLER_GPIO_ANALOG_JOYSTICK) */

s = digitalRead(HW_CONTROLLER_GPIO_SELECT);
t = digitalRead(HW_CONTROLLER_GPIO_START);
a = digitalRead(HW_CONTROLLER_GPIO_A);
b = digitalRead(HW_CONTROLLER_GPIO_B);
x = digitalRead(HW_CONTROLLER_GPIO_X);
y = digitalRead(HW_CONTROLLER_GPIO_Y);

return 0xFFFFFFFF ^ ((!u << 0) | (!d << 1) | (!l << 2) | (!r << 3) | (!s << 4) | (!t << 5) | (!a << 6) | (!b << 7) | (!x << 8) | (!y << 9));
}

/* controller is I2C M5Stack CardKB */
#elif defined(HW_CONTROLLER_I2C_M5CARDKB)

#include <Wire.h>

#define I2C_M5CARDKB_ADDR 0x5f
#define READ_BIT I2C_MASTER_READ /*!< I2C master read */
#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave */
#define NACK_VAL 0x1 /*!< I2C nack value */

extern "C" void controller_init()
{
Wire.begin();
}

extern "C" uint32_t controller_read_input()
{
uint32_t value = 0xFFFFFFFF;

Wire.requestFrom(I2C_M5CARDKB_ADDR, 1);
while (Wire.available())
{
char c = Wire.read(); // receive a byte as characterif
if (c != 0)
{
switch (c)
{
case 181: // up
value ^= (1 << 0);
break;
case 182: // down
value ^= (1 << 1);
break;
case 180: // left
value ^= (1 << 2);
break;
case 183: // right
value ^= (1 << 3);
break;
case ' ': // select
value ^= (1 << 4);
break;
case 13: // enter -> start
value ^= (1 << 5);
break;
case 'k': // A
value ^= (1 << 6);
break;
case 'l': // B
value ^= (1 << 7);
break;
case 'o': // X
value ^= (1 << 8);
break;
case 'p': // Y
value ^= (1 << 9);
break;
}
}
}

return value;
}

/* controller is I2C BBQ10Keyboard */
#elif defined(HW_CONTROLLER_I2C_BBQ10KB)

#include <Wire.h>
#include <BBQ10Keyboard.h>
BBQ10Keyboard keyboard;
static uint32_t value = 0xFFFFFFFF;

extern "C" void controller_init()
{
Wire.begin();
keyboard.begin();
keyboard.setBacklight(0.2f);
}

extern "C" uint32_t controller_read_input()
{

int keyCount = keyboard.keyCount();
while (keyCount--)
{
const BBQ10Keyboard::KeyEvent key = keyboard.keyEvent();
String state = "pressed";
if (key.state == BBQ10Keyboard::StateLongPress)
state = "held down";
else if (key.state == BBQ10Keyboard::StateRelease)
state = "released";

// Serial.printf("key: '%c' (dec %d, hex %02x) %s\r\n", key.key, key.key, key.key, state.c_str());

uint32_t bit = 0;
if (key.key != 0)
{
switch (key.key)
{
case 'w': // up
bit = (1 << 0);
break;
case 'z': // down
bit = (1 << 1);
break;
case 'a': // left
bit = (1 << 2);
break;
case 'd': // right
bit = (1 << 3);
break;
case ' ': // select
bit = (1 << 4);
break;
case 10: // enter -> start
bit = (1 << 5);
break;
case 'k': // A
bit = (1 << 6);
break;
case 'l': // B
bit = (1 << 7);
break;
case 'o': // X
bit = (1 << 8);
break;
case 'p': // Y
bit = (1 << 9);
break;
}
if (key.state == BBQ10Keyboard::StatePress)
{
value ^= bit;
}
else if (key.state == BBQ10Keyboard::StateRelease)
{
value |= bit;
}
}
}

return value;
}

#else /* no controller defined */

extern "C" void controller_init()
{
Serial.printf("GPIO controller disabled in menuconfig; no input enabled.\n");
}

extern "C" uint32_t controller_read_input()
{
return 0xFFFFFFFF;
}

#endif /* no controller defined */
Binary file added examples/esp32-nofrendo/data/Chase.nes
Binary file not shown.
4 changes: 4 additions & 0 deletions examples/esp32-nofrendo/data/Chase.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
This is an example game that is developed for my article Programming NES games in C. The article itself is located at my website in the Articles section, to make things simpler in case of possible updates.

http://shiru.untergrund.net
mailto:shiru@mail.ru
197 changes: 197 additions & 0 deletions examples/esp32-nofrendo/display.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
extern "C"
{
#include <nes/nes.h>
}

#include "hw_config.h"

#include <Arduino_GFX_Library.h>

/* M5Stack */
#if defined(ARDUINO_M5Stack_Core_ESP32) || defined(ARDUINO_M5STACK_FIRE)

#define TFT_BRIGHTNESS 255 /* 0 - 255 */
#define TFT_BL 32
Arduino_DataBus *bus = new Arduino_ESP32SPI(27 /* DC */, 14 /* CS */, SCK, MOSI, MISO);
Arduino_ILI9342 *gfx = new Arduino_ILI9342(bus, 33 /* RST */, 1 /* rotation */);

/* Odroid-Go */
#elif defined(ARDUINO_ODROID_ESP32)

#define TFT_BRIGHTNESS 191 /* 0 - 255 */
#define TFT_BL 14
Arduino_DataBus *bus = new Arduino_ESP32SPI(21 /* DC */, 5 /* CS */, SCK, MOSI, MISO);
Arduino_ILI9341 *gfx = new Arduino_ILI9341(bus, -1 /* RST */, 3 /* rotation */);

/* TTGO T-Watch */
#elif defined(ARDUINO_T) || defined(ARDUINO_TWATCH_BASE) || defined(ARDUINO_TWATCH_2020_V1) || defined(ARDUINO_TWATCH_2020_V2) // TTGO T-Watch

#define TFT_BRIGHTNESS 255 /* 0 - 255 */
#define TFT_BL 12
Arduino_DataBus *bus = new Arduino_ESP32SPI(27 /* DC */, 5 /* CS */, 18 /* SCK */, 19 /* MOSI */, -1 /* MISO */);
Arduino_ST7789 *gfx = new Arduino_ST7789(bus, -1 /* RST */, 1 /* rotation */, true /* IPS */, 240, 240, 0, 80);

/* custom hardware */
#else

#define TFT_BRIGHTNESS 128 /* 0 - 255 */

/* HX8357B */
// #define TFT_BL 27
// Arduino_DataBus *bus = new Arduino_ESP32SPI(-1 /* DC */, 5 /* CS */, 18 /* SCK */, 23 /* MOSI */, -1 /* MISO */);
// Arduino_TFT *gfx = new Arduino_HX8357B(bus, 33, 3 /* rotation */, true /* IPS */);

/* ST7789 ODROID Compatible pin connection */
// #define TFT_BL 14
// Arduino_DataBus *bus = new Arduino_ESP32SPI(21 /* DC */, 5 /* CS */, SCK, MOSI, MISO);
// Arduino_ST7789 *gfx = new Arduino_ST7789(bus, -1 /* RST */, 1 /* rotation */, true /* IPS */);

/* ST7796 on breadboard */
// #define TFT_BL 32
Arduino_DataBus *bus = new Arduino_ESP32SPI(32 /* DC */, -1 /* CS */, 25 /* SCK */, 33 /* MOSI */, -1 /* MISO */);
Arduino_TFT *gfx = new Arduino_ST7796(bus, -1 /* RST */, 1 /* rotation */);

/* ST7796 on LCDKit */
// #define TFT_BL 23
// Arduino_DataBus *bus = new Arduino_ESP32SPI(19 /* DC */, 5 /* CS */, 22 /* SCK */, 21 /* MOSI */, -1 /* MISO */);
// Arduino_ST7796 *gfx = new Arduino_ST7796(bus, 18, 1 /* rotation */);

#endif /* custom hardware */

static int16_t w, h, frame_x, frame_y, frame_x_offset, frame_width, frame_height, frame_line_pixels;
extern int16_t bg_color;
extern uint16_t myPalette[];

extern void display_begin()
{
gfx->begin();
bg_color = gfx->color565(24, 28, 24); // DARK DARK GREY
gfx->fillScreen(bg_color);

#ifdef TFT_BL
// turn display backlight on
ledcSetup(1, 12000, 8); // 12 kHz PWM, 8-bit resolution
ledcAttachPin(TFT_BL, 1); // assign TFT_BL pin to channel 1
ledcWrite(1, TFT_BRIGHTNESS); // brightness 0 - 255
#endif
}

extern "C" void display_init()
{
w = gfx->width();
h = gfx->height();
if (w < 480) // assume only 240x240 or 320x240
{
if (w > NES_SCREEN_WIDTH)
{
frame_x = (w - NES_SCREEN_WIDTH) / 2;
frame_x_offset = 0;
frame_width = NES_SCREEN_WIDTH;
frame_height = NES_SCREEN_HEIGHT;
frame_line_pixels = frame_width;
}
else
{
frame_x = 0;
frame_x_offset = (NES_SCREEN_WIDTH - w) / 2;
frame_width = w;
frame_height = NES_SCREEN_HEIGHT;
frame_line_pixels = frame_width;
}
frame_y = (gfx->height() - NES_SCREEN_HEIGHT) / 2;
}
else // assume 480x320
{
frame_x = 0;
frame_y = 0;
frame_x_offset = 8;
frame_width = w;
frame_height = h;
frame_line_pixels = frame_width / 2;
}
}

extern "C" void display_write_frame(const uint8_t *data[])
{
gfx->startWrite();
if (w < 480)
{
gfx->writeAddrWindow(frame_x, frame_y, frame_width, frame_height);
for (int32_t i = 0; i < NES_SCREEN_HEIGHT; i++)
{
gfx->writeIndexedPixels((uint8_t *)(data[i] + frame_x_offset), myPalette, frame_line_pixels);
}
}
else
{
/* ST7796 480 x 320 resolution */

/* Option 1:
* crop 256 x 240 to 240 x 214
* then scale up width x 2 and scale up height x 1.5
* repeat a line for every 2 lines
*/
// gfx->writeAddrWindow(frame_x, frame_y, frame_width, frame_height);
// for (int16_t i = 10; i < (10 + 214); i++)
// {
// gfx->writeIndexedPixelsDouble((uint8_t *)(data[i] + 8), myPalette, frame_line_pixels);
// if ((i % 2) == 1)
// {
// gfx->writeIndexedPixelsDouble((uint8_t *)(data[i] + 8), myPalette, frame_line_pixels);
// }
// }

/* Option 2:
* crop 256 x 240 to 240 x 214
* then scale up width x 2 and scale up height x 1.5
* simply blank a line for every 2 lines
*/
int16_t y = 0;
for (int16_t i = 10; i < (10 + 214); i++)
{
gfx->writeAddrWindow(frame_x, y++, frame_width, 1);
gfx->writeIndexedPixelsDouble((uint8_t *)(data[i] + 8), myPalette, frame_line_pixels);
if ((i % 2) == 1)
{
y++; // blank line
}
}

/* Option 3:
* crop 256 x 240 to 240 x 240
* then scale up width x 2 and scale up height x 1.33
* repeat a line for every 3 lines
*/
// gfx->writeAddrWindow(frame_x, frame_y, frame_width, frame_height);
// for (int16_t i = 0; i < 240; i++)
// {
// gfx->writeIndexedPixelsDouble((uint8_t *)(data[i] + 8), myPalette, frame_line_pixels);
// if ((i % 3) == 1)
// {
// gfx->writeIndexedPixelsDouble((uint8_t *)(data[i] + 8), myPalette, frame_line_pixels);
// }
// }

/* Option 4:
* crop 256 x 240 to 240 x 240
* then scale up width x 2 and scale up height x 1.33
* simply blank a line for every 3 lines
*/
// int16_t y = 0;
// for (int16_t i = 0; i < 240; i++)
// {
// gfx->writeAddrWindow(frame_x, y++, frame_width, 1);
// gfx->writeIndexedPixelsDouble((uint8_t *)(data[i] + 8), myPalette, frame_line_pixels);
// if ((i % 3) == 1)
// {
// y++; // blank line
// }
// }
}
gfx->endWrite();
}

extern "C" void display_clear()
{
gfx->fillScreen(bg_color);
}
92 changes: 92 additions & 0 deletions examples/esp32-nofrendo/esp32-nofrendo.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/* Arduino Nofrendo
* Please check hw_config.h and display.cpp for configuration details
*/
#include <esp_wifi.h>
#include <esp_task_wdt.h>
#include <FFat.h>
#include <SPIFFS.h>
#include <SD.h>
#include <SD_MMC.h>

#include <Arduino_GFX_Library.h>

#include "hw_config.h"

extern "C"
{
#include <nofrendo.h>
}

int16_t bg_color;
extern Arduino_TFT *gfx;
extern void display_begin();

void setup()
{
Serial.begin(115200);

// turn off WiFi
esp_wifi_deinit();

// disable Core 0 WDT
TaskHandle_t idle_0 = xTaskGetIdleTaskHandleForCPU(0);
esp_task_wdt_delete(idle_0);

// start display
display_begin();

// filesystem defined in hw_config.h
FILESYSTEM_BEGIN

// find first rom file (*.nes)
File root = filesystem.open("/");
char *argv[1];
if (!root)
{
Serial.println("Filesystem mount failed! Please check hw_config.h settings.");
gfx->println("Filesystem mount failed! Please check hw_config.h settings.");
}
else
{
bool foundRom = false;

File file = root.openNextFile();
while (file)
{
if (file.isDirectory())
{
// skip
}
else
{
char *filename = (char *)file.name();
int8_t len = strlen(filename);
if (strstr(strlwr(filename + (len - 4)), ".nes"))
{
foundRom = true;
char fullFilename[256];
sprintf(fullFilename, "%s/%s", FSROOT, filename);
Serial.println(fullFilename);
argv[0] = fullFilename;
break;
}
}

file = root.openNextFile();
}

if (!foundRom)
{
Serial.println("Failed to find rom file, please copy rom file to data folder and upload with \"ESP32 Sketch Data Upload\"");
argv[0] = "/";
}

Serial.println("NoFrendo start!\n");
nofrendo_main(1, argv);
Serial.println("NoFrendo end!\n");
}
}

void loop()
{
}
113 changes: 113 additions & 0 deletions examples/esp32-nofrendo/hw_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#ifndef _HW_CONFIG_H_
#define _HW_CONFIG_H_

#define FSROOT "/fs"

/* M5Stack */
#if defined(ARDUINO_M5Stack_Core_ESP32) || defined(ARDUINO_M5STACK_FIRE)

// Uncomment one of below, M5Stack support SPIFFS and SD
// #define FILESYSTEM_BEGIN SPIFFS.begin(false, FSROOT); FS filesystem = SPIFFS;
#define FILESYSTEM_BEGIN SD.begin(4, SPI, 40000000, FSROOT); FS filesystem = SD;

/* enable audio */
#define HW_AUDIO
#define HW_AUDIO_SAMPLERATE 22050

/* controller is I2C M5Stack CardKB */
#define HW_CONTROLLER_I2C_M5CARDKB

/* Odroid-Go */
#elif defined(ARDUINO_ODROID_ESP32)

// Uncomment one of below, ODROID support SPIFFS and SD
// #define FILESYSTEM_BEGIN SPIFFS.begin(false, FSROOT); FS filesystem = SPIFFS;
#define FILESYSTEM_BEGIN SD.begin(SS, SPI, 40000000, FSROOT); FS filesystem = SD;

/* enable audio */
#define HW_AUDIO
#define HW_AUDIO_SAMPLERATE 22050

/* controller is GPIO */
#define HW_CONTROLLER_GPIO
#define HW_CONTROLLER_GPIO_ANALOG_JOYSTICK
#define HW_CONTROLLER_GPIO_UP_DOWN 35
#define HW_CONTROLLER_GPIO_LEFT_RIGHT 34
#define HW_CONTROLLER_GPIO_SELECT 27
#define HW_CONTROLLER_GPIO_START 39
#define HW_CONTROLLER_GPIO_A 32
#define HW_CONTROLLER_GPIO_B 33
#define HW_CONTROLLER_GPIO_X 13
#define HW_CONTROLLER_GPIO_Y 0

/* TTGO T-Watch */
#elif defined(ARDUINO_T) || defined(ARDUINO_TWATCH_BASE) || defined(ARDUINO_TWATCH_2020_V1) || defined(ARDUINO_TWATCH_2020_V2) // TTGO T-Watch

// TTGO T-watch with game module only support SPIFFS
#define FILESYSTEM_BEGIN SPIFFS.begin(false, FSROOT); FS filesystem = SPIFFS;

/* buzzer audio */
#define HW_AUDIO_BUZZER
#define HW_AUDIO_BUZZER_PIN 4
#define HW_AUDIO_SAMPLERATE 22050 // nofrendo minimum sample rate

/* controller is GPIO */
#define HW_CONTROLLER_GPIO
#define HW_CONTROLLER_GPIO_ANALOG_JOYSTICK
#define HW_CONTROLLER_GPIO_UP_DOWN 34
#define HW_CONTROLLER_GPIO_LEFT_RIGHT 33
#define HW_CONTROLLER_GPIO_SELECT 15
#define HW_CONTROLLER_GPIO_START 36
#define HW_CONTROLLER_GPIO_A 13
#define HW_CONTROLLER_GPIO_B 25
#define HW_CONTROLLER_GPIO_X 14
#define HW_CONTROLLER_GPIO_Y 26

/* custom hardware */
#else

// Uncomment one of below, ESP32 support SPIFFS SD_MMC and SD
/* FatFS */
// #define FILESYSTEM_BEGIN FFat.begin(false, FSROOT); FS filesystem = FFat;
/* SPIFFS */
// #define FILESYSTEM_BEGIN SPIFFS.begin(false, FSROOT); FS filesystem = SPIFFS;
/* 1-bit SD mode SD_MMC, always retry once for begin() failed */
// #define FILESYSTEM_BEGIN (!SD_MMC.begin(FSROOT, true)) && (!SD_MMC.begin(FSROOT, true)); FS filesystem = SD_MMC;
/* 4-bit SD mode SD_MMC, always retry once for begin() failed */
// #define FILESYSTEM_BEGIN (!SD_MMC.begin(FSROOT, false)) && (!SD_MMC.begin(FSROOT, false)); FS filesystem = SD_MMC;
/* SD using default SPI settings */
// #define FILESYSTEM_BEGIN SD.begin(22 /* SS */, SPI, 8000000, FSROOT); FS filesystem = SD;
/* SD using custom SPI settings */
#define FILESYSTEM_BEGIN SPIClass spi = SPIClass(HSPI); spi.begin(14, 2, 15, 13); SD.begin(13, spi, 8000000, FSROOT); FS filesystem = SD;

// enable audio
#define HW_AUDIO
#define HW_AUDIO_EXTDAC
#define HW_AUDIO_EXTDAC_WCLK 21
#define HW_AUDIO_EXTDAC_BCLK 22
#define HW_AUDIO_EXTDAC_DOUT 19
#define HW_AUDIO_SAMPLERATE 22050

/* controller is GPIO */
#define HW_CONTROLLER_GPIO
#define HW_CONTROLLER_GPIO_ANALOG_JOYSTICK
// #define HW_CONTROLLER_GPIO_REVERSE_UD
#define HW_CONTROLLER_GPIO_UP_DOWN 34
#define HW_CONTROLLER_GPIO_REVERSE_LF
#define HW_CONTROLLER_GPIO_LEFT_RIGHT 35
#define HW_CONTROLLER_GPIO_SELECT 27
#define HW_CONTROLLER_GPIO_START 26
#define HW_CONTROLLER_GPIO_A 5
#define HW_CONTROLLER_GPIO_B 4
#define HW_CONTROLLER_GPIO_X 23
#define HW_CONTROLLER_GPIO_Y 18

/* controller is I2C M5Stack CardKB */
// #define HW_CONTROLLER_I2C_M5CARDKB

/* controller is I2C BBQ10Keyboard */
// #define HW_CONTROLLER_I2C_BBQ10KB

#endif /* custom hardware */

#endif /* _HW_CONFIG_H_ */
261 changes: 261 additions & 0 deletions examples/esp32-nofrendo/osd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
/* start rewrite from: https://github.com/espressif/esp32-nesemu.git */
#include <string.h>

#include <freertos/FreeRTOS.h>
#include <freertos/timers.h>
#include <freertos/task.h>
#include <freertos/queue.h>

#include <esp_heap_caps.h>

#include <noftypes.h>

#include <event.h>
#include <gui.h>
#include <log.h>
#include <nes/nes.h>
#include <nes/nes_pal.h>
#include <nes/nesinput.h>
#include <nofconfig.h>
#include <osd.h>

#include "hw_config.h"

TimerHandle_t timer;

/* memory allocation */
extern void *mem_alloc(int size, bool prefer_fast_memory)
{
if (prefer_fast_memory)
{
return heap_caps_malloc(size, MALLOC_CAP_8BIT);
}
else
{
return heap_caps_malloc_prefer(size, MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT);
}
}

/* sound */
extern int osd_init_sound();
extern void osd_stopsound();
extern void do_audio_frame();
extern void osd_getsoundinfo(sndinfo_t *info);

/* display */
extern void display_init();
extern void display_write_frame(const uint8_t *data[]);
extern void display_clear();

//This runs on core 0.
QueueHandle_t vidQueue;
static void displayTask(void *arg)
{
bitmap_t *bmp = NULL;
while (1)
{
// xQueueReceive(vidQueue, &bmp, portMAX_DELAY); //skip one frame to drop to 30
xQueueReceive(vidQueue, &bmp, portMAX_DELAY);
display_write_frame((const uint8_t **)bmp->line);
}
}

/* get info */
static char fb[1]; //dummy
bitmap_t *myBitmap;

/* initialise video */
static int init(int width, int height)
{
return 0;
}

static void shutdown(void)
{
}

/* set a video mode */
static int set_mode(int width, int height)
{
return 0;
}

/* copy nes palette over to hardware */
uint16 myPalette[256];
static void set_palette(rgb_t *pal)
{
uint16 c;

int i;

for (i = 0; i < 256; i++)
{
c = (pal[i].b >> 3) + ((pal[i].g >> 2) << 5) + ((pal[i].r >> 3) << 11);
//myPalette[i]=(c>>8)|((c&0xff)<<8);
myPalette[i] = c;
}
}

/* clear all frames to a particular color */
static void clear(uint8 color)
{
// SDL_FillRect(mySurface, 0, color);
display_clear();
}

/* acquire the directbuffer for writing */
static bitmap_t *lock_write(void)
{
// SDL_LockSurface(mySurface);
myBitmap = bmp_createhw((uint8 *)fb, NES_SCREEN_WIDTH, NES_SCREEN_HEIGHT, NES_SCREEN_WIDTH * 2);
return myBitmap;
}

/* release the resource */
static void free_write(int num_dirties, rect_t *dirty_rects)
{
bmp_destroy(&myBitmap);
}

static void custom_blit(bitmap_t *bmp, int num_dirties, rect_t *dirty_rects)
{
xQueueSend(vidQueue, &bmp, 0);
do_audio_frame();
}

viddriver_t sdlDriver =
{
"Simple DirectMedia Layer", /* name */
init, /* init */
shutdown, /* shutdown */
set_mode, /* set_mode */
set_palette, /* set_palette */
clear, /* clear */
lock_write, /* lock_write */
free_write, /* free_write */
custom_blit, /* custom_blit */
false /* invalidate flag */
};

void osd_getvideoinfo(vidinfo_t *info)
{
info->default_width = NES_SCREEN_WIDTH;
info->default_height = NES_SCREEN_HEIGHT;
info->driver = &sdlDriver;
}

/* input */
extern void controller_init();
extern uint32_t controller_read_input();

static void osd_initinput()
{
controller_init();
}

static void osd_freeinput(void)
{
}

void osd_getinput(void)
{
const int ev[32] = {
event_joypad1_up, event_joypad1_down, event_joypad1_left, event_joypad1_right,
event_joypad1_select, event_joypad1_start, event_joypad1_a, event_joypad1_b,
event_state_save, event_state_load, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0};
static int oldb = 0xffff;
uint32_t b = controller_read_input();
uint32_t chg = b ^ oldb;
int x;
oldb = b;
event_t evh;
// nofrendo_log_printf("Input: %x\n", b);
for (x = 0; x < 16; x++)
{
if (chg & 1)
{
evh = event_get(ev[x]);
if (evh)
evh((b & 1) ? INP_STATE_BREAK : INP_STATE_MAKE);
}
chg >>= 1;
b >>= 1;
}
}

void osd_getmouse(int *x, int *y, int *button)
{
}

/* init / shutdown */
static int logprint(const char *string)
{
return printf("%s", string);
}

int osd_init()
{
nofrendo_log_chain_logfunc(logprint);

if (osd_init_sound())
return -1;

display_init();
vidQueue = xQueueCreate(1, sizeof(bitmap_t *));
// xTaskCreatePinnedToCore(&displayTask, "displayTask", 2048, NULL, 5, NULL, 1);
xTaskCreatePinnedToCore(&displayTask, "displayTask", 2048, NULL, 0, NULL, 0);
osd_initinput();
return 0;
}

void osd_shutdown()
{
osd_stopsound();
osd_freeinput();
}

char configfilename[] = "na";
int osd_main(int argc, char *argv[])
{
config.filename = configfilename;

return main_loop(argv[0], system_autodetect);
}

//Seemingly, this will be called only once. Should call func with a freq of frequency,
int osd_installtimer(int frequency, void *func, int funcsize, void *counter, int countersize)
{
nofrendo_log_printf("Timer install, configTICK_RATE_HZ=%d, freq=%d\n", configTICK_RATE_HZ, frequency);
timer = xTimerCreate("nes", configTICK_RATE_HZ / frequency, pdTRUE, NULL, func);
xTimerStart(timer, 0);
return 0;
}

/* filename manipulation */
void osd_fullname(char *fullname, const char *shortname)
{
strncpy(fullname, shortname, PATH_MAX);
}

/* This gives filenames for storage of saves */
char *osd_newextension(char *string, char *ext)
{
// dirty: assume both extensions is 3 characters
size_t l = strlen(string);
string[l - 3] = ext[1];
string[l - 2] = ext[2];
string[l - 1] = ext[3];

return string;
}

/* This gives filenames for storage of PCX snapshots */
int osd_makesnapname(char *filename, int len)
{
return -1;
}
217 changes: 217 additions & 0 deletions examples/esp32-nofrendo/sound.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
/*
* Buzzer part start rewrite from: https://github.com/moononournation/esp_8_bit.git
*/
#include <freertos/FreeRTOS.h>
#include <freertos/timers.h>
#include <freertos/task.h>
#include <freertos/queue.h>

#include <driver/i2s.h>
#include <soc/ledc_struct.h>
#include <esp32-hal-timer.h>

#include <nes/nes.h>

#include "hw_config.h"

#if defined(HW_AUDIO)

#define DEFAULT_FRAGSIZE 64
static void (*audio_callback)(void *buffer, int length) = NULL;
QueueHandle_t queue;
static int16_t *audio_frame;

int osd_init_sound()
{
audio_frame = NOFRENDO_MALLOC(4 * DEFAULT_FRAGSIZE);

i2s_config_t cfg = {
#if defined(HW_AUDIO_EXTDAC)
.mode = I2S_MODE_MASTER | I2S_MODE_TX,
#else /* !defined(HW_AUDIO_EXTDAC) */
.mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN,
#endif /* !defined(HW_AUDIO_EXTDAC) */
.sample_rate = HW_AUDIO_SAMPLERATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
#if defined(HW_AUDIO_EXTDAC)
.communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
#else /* !defined(HW_AUDIO_EXTDAC) */
.communication_format = I2S_COMM_FORMAT_PCM | I2S_COMM_FORMAT_I2S_MSB,
#endif /* !defined(HW_AUDIO_EXTDAC) */
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 7,
.dma_buf_len = 256,
.use_apll = false,
};
i2s_driver_install(I2S_NUM_0, &cfg, 2, &queue);
#if defined(HW_AUDIO_EXTDAC)
i2s_pin_config_t pins = {
.bck_io_num = HW_AUDIO_EXTDAC_BCLK,
.ws_io_num = HW_AUDIO_EXTDAC_WCLK,
.data_out_num = HW_AUDIO_EXTDAC_DOUT,
.data_in_num = I2S_PIN_NO_CHANGE,
};
i2s_set_pin(I2S_NUM_0, &pins);
#else /* !defined(HW_AUDIO_EXTDAC) */
i2s_set_pin(I2S_NUM_0, NULL);
i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN);
#endif /* !defined(HW_AUDIO_EXTDAC) */
i2s_zero_dma_buffer(I2S_NUM_0);

audio_callback = NULL;

return 0;
}

void osd_stopsound()
{
audio_callback = NULL;
}

void do_audio_frame()
{
int left = HW_AUDIO_SAMPLERATE / NES_REFRESH_RATE;
while (left)
{
int n = DEFAULT_FRAGSIZE;
if (n > left)
n = left;
audio_callback(audio_frame, n); //get more data

//16 bit mono -> 32-bit (16 bit r+l)
int16_t *mono_ptr = audio_frame + n;
int16_t *stereo_ptr = audio_frame + n + n;
int i = n;
while (i--)
{
#if defined(HW_AUDIO_EXTDAC)
int16_t a = (*(--mono_ptr) >> 2);
*(--stereo_ptr) = a;
*(--stereo_ptr) = a;
#else /* !defined(HW_AUDIO_EXTDAC) */
int16_t a = (*(--mono_ptr) >> 3);
*(--stereo_ptr) = 0x8000 + a;
*(--stereo_ptr) = 0x8000 - a;
#endif /* !defined(HW_AUDIO_EXTDAC) */
}

size_t i2s_bytes_write;
i2s_write(I2S_NUM_0, (const char *)audio_frame, 4 * n, &i2s_bytes_write, portMAX_DELAY);
left -= i2s_bytes_write / 4;
}
}

void osd_setsound(void (*playfunc)(void *buffer, int length))
{
//Indicates we should call playfunc() to get more data.
audio_callback = playfunc;
}

void osd_getsoundinfo(sndinfo_t *info)
{
info->sample_rate = HW_AUDIO_SAMPLERATE;
info->bps = 16;
}

#elif defined(HW_AUDIO_BUZZER)

#define DEFAULT_FRAGSIZE (HW_AUDIO_SAMPLERATE / NES_REFRESH_RATE)
static void (*audio_callback)(void *buffer, int length) = NULL;
static int16_t *audio_frame;

hw_timer_t *timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;

volatile uint32_t audio_frame_idx = 0;

void IRAM_ATTR audioSampleTimer()
{
audio_frame_idx++;
if (audio_frame_idx >= DEFAULT_FRAGSIZE)
{
audio_frame_idx = 0;
}

uint16_t s = audio_frame[audio_frame_idx];
LEDC.channel_group[0].channel[2].duty.duty = s >> 3;
LEDC.channel_group[0].channel[2].conf0.sig_out_en = 1; // This is the output enable control bit for channel
LEDC.channel_group[0].channel[2].conf1.duty_start = 1; // When duty_num duty_cycle and duty_scale has been configured. these register won't take effect until set duty_start. this bit is automatically cleared by hardware
LEDC.channel_group[0].channel[2].conf0.clk_en = 1;
}

int osd_init_sound()
{
audio_frame = NOFRENDO_MALLOC(4 * DEFAULT_FRAGSIZE);

ledcSetup(2, 2000000, 10);
ledcAttachPin(HW_AUDIO_BUZZER_PIN, 2);
ledcWrite(2, 0);

// Use 1st timer of 4 (counted from zero).
// Set 80 divider for prescaler (see ESP32 Technical Reference Manual for more
// info).
timer = timerBegin(0, 80, true);

// Attach audioSampleTimer function to our timer.
timerAttachInterrupt(timer, &audioSampleTimer, true);

// Set alarm to call audioSampleTimer function every second (value in microseconds).
// Repeat the alarm (third parameter)
timerAlarmWrite(timer, 1000000 / HW_AUDIO_SAMPLERATE, true);

// Start an alarm
timerAlarmEnable(timer);

return 0;
}

void osd_stopsound()
{
audio_callback = NULL;
}

void do_audio_frame()
{
audio_callback(audio_frame, DEFAULT_FRAGSIZE); //get more data
}

void osd_setsound(void (*playfunc)(void *buffer, int length))
{
//Indicates we should call playfunc() to get more data.
audio_callback = playfunc;
}

void osd_getsoundinfo(sndinfo_t *info)
{
info->sample_rate = HW_AUDIO_SAMPLERATE;
info->bps = 16;
}

#else /* !defined(HW_AUDIO) */

int osd_init_sound()
{
return 0;
}

void osd_stopsound()
{
}

void do_audio_frame()
{
}

void osd_setsound(void (*playfunc)(void *buffer, int length))
{
}

void osd_getsoundinfo(sndinfo_t *info)
{
// dummy value
info->sample_rate = 22050;
info->bps = 16;
}

#endif /* !defined(HW_AUDIO) */
251 changes: 0 additions & 251 deletions install-sh

This file was deleted.

7 changes: 7 additions & 0 deletions library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name=arduino-nofrendo
version=1.2
author=Matt Conte <zeus@ztnet.com>, Neil Stevens <neil@qualityassistant.com>, Firebug <firebug@cfl.rr.com>, Benjamin C. W. Sittler <bsittler@nmt.edu>, The Mighty Mike Master <melanson@pcisys.net>
maintainer=Moon On Our Nation <moononournation@gmail.com>
sentence=Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com)
paragraph=This is a special nofrendo version as a Arduino library.
url=https://github.com/moononournation/arduino-nofrendo
190 changes: 0 additions & 190 deletions missing

This file was deleted.

40 changes: 0 additions & 40 deletions mkinstalldirs

This file was deleted.

19 changes: 0 additions & 19 deletions src/Makefile.am

This file was deleted.

404 changes: 0 additions & 404 deletions src/Makefile.in

This file was deleted.

3 changes: 0 additions & 3 deletions src/beos/Makefile.am

This file was deleted.

300 changes: 0 additions & 300 deletions src/beos/Makefile.in

This file was deleted.

212 changes: 0 additions & 212 deletions src/beos/osd.c

This file was deleted.

309 changes: 155 additions & 154 deletions src/bitmap.c
Original file line number Diff line number Diff line change
@@ -1,154 +1,155 @@
/*
** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com)
**
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of version 2 of the GNU Library General
** Public License as published by the Free Software Foundation.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** Library General Public License for more details. To obtain a
** copy of the GNU Library General Public License, write to the Free
** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**
** Any permitted reproduction of these routines, in whole or in part,
** must bear this legend.
**
**
** bitmap.c
**
** Bitmap object manipulation routines
** $Id: bitmap.c,v 1.2 2001/04/27 14:37:11 neil Exp $
*/

#include <stdio.h>
#include <string.h>
#include <noftypes.h>
#include <bitmap.h>

void bmp_clear(const bitmap_t *bitmap, uint8 color)
{
memset(bitmap->data, color, bitmap->pitch * bitmap->height);
}

static bitmap_t *_make_bitmap(uint8 *data_addr, bool hw, int width,
int height, int pitch, int overdraw)
{
bitmap_t *bitmap;
int i;

/* quick safety check */
if (NULL == data_addr)
return NULL;

/* Make sure to add in space for line pointers */
bitmap = malloc(sizeof(bitmap_t) + (sizeof(uint8 *) * height));
if (NULL == bitmap)
return NULL;

bitmap->hardware = hw;
bitmap->height = height;
bitmap->width = width;
bitmap->data = data_addr;
bitmap->pitch = pitch + (overdraw * 2);

/* Set up line pointers */
/* we want to make some 32-bit aligned adjustment
** if we haven't been given a hardware bitmap
*/
if (false == bitmap->hardware)
{
bitmap->pitch = (bitmap->pitch + 3) & ~3;
bitmap->line[0] = (uint8 *) (((uint32) bitmap->data + overdraw + 3) & ~3);
}
else
{
bitmap->line[0] = bitmap->data + overdraw;
}

for (i = 1; i < height; i++)
bitmap->line[i] = bitmap->line[i - 1] + bitmap->pitch;

return bitmap;
}

/* Allocate and initialize a bitmap structure */
bitmap_t *bmp_create(int width, int height, int overdraw)
{
uint8 *addr;
int pitch;

pitch = width + (overdraw * 2); /* left and right */

addr = malloc((pitch * height) + 3); /* add max 32-bit aligned adjustment */
if (NULL == addr)
return NULL;

return _make_bitmap(addr, false, width, height, width, overdraw);
}

/* allocate and initialize a hardware bitmap */
bitmap_t *bmp_createhw(uint8 *addr, int width, int height, int pitch)
{
return _make_bitmap(addr, true, width, height, pitch, 0); /* zero overdraw */
}

/* Deallocate space for a bitmap structure */
void bmp_destroy(bitmap_t **bitmap)
{
if (*bitmap)
{
if ((*bitmap)->data && false == (*bitmap)->hardware)
free((*bitmap)->data);
free(*bitmap);
*bitmap = NULL;
}
}

/*
** $Log: bitmap.c,v $
** Revision 1.2 2001/04/27 14:37:11 neil
** wheeee
**
** Revision 1.1.1.1 2001/04/27 07:03:54 neil
** initial
**
** Revision 1.16 2000/11/05 16:37:18 matt
** rolled rgb.h into bitmap.h
**
** Revision 1.15 2000/10/10 13:58:13 matt
** stroustrup squeezing his way in the door
**
** Revision 1.14 2000/09/18 02:06:48 matt
** -pedantic is your friend
**
** Revision 1.13 2000/08/13 13:16:30 matt
** bugfix for alignment adjustment
**
** Revision 1.12 2000/07/24 04:31:43 matt
** pitch/data area on non-hw bitmaps get padded to 32-bit boundaries
**
** Revision 1.11 2000/07/17 01:52:27 matt
** made sure last line of all source files is a newline
**
** Revision 1.10 2000/07/09 14:43:01 matt
** pitch is now configurable for bmp_createhw()
**
** Revision 1.9 2000/07/06 17:55:57 matt
** two big bugs fixed
**
** Revision 1.8 2000/07/06 17:38:11 matt
** replaced missing string.h include
**
** Revision 1.7 2000/07/06 16:46:57 matt
** added bmp_clear() routine
**
** Revision 1.6 2000/06/26 04:56:24 matt
** minor cleanup
**
** Revision 1.5 2000/06/09 15:12:25 matt
** initial revision
**
*/
/*
** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com)
**
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of version 2 of the GNU Library General
** Public License as published by the Free Software Foundation.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** Library General Public License for more details. To obtain a
** copy of the GNU Library General Public License, write to the Free
** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**
** Any permitted reproduction of these routines, in whole or in part,
** must bear this legend.
**
**
** bitmap.c
**
** Bitmap object manipulation routines
** $Id: bitmap.c,v 1.2 2001/04/27 14:37:11 neil Exp $
*/

#include <stdio.h>
#include <string.h>

#include "noftypes.h"
#include "bitmap.h"

void bmp_clear(const bitmap_t *bitmap, uint8 color)
{
memset(bitmap->data, color, bitmap->pitch * bitmap->height);
}

static bitmap_t *_make_bitmap(uint8 *data_addr, bool hw, int width,
int height, int pitch, int overdraw)
{
bitmap_t *bitmap;
int i;

/* quick safety check */
if (NULL == data_addr)
return NULL;

/* Make sure to add in space for line pointers */
bitmap = NOFRENDO_MALLOC(sizeof(bitmap_t) + (sizeof(uint8 *) * height));
if (NULL == bitmap)
return NULL;

bitmap->hardware = hw;
bitmap->height = height;
bitmap->width = width;
bitmap->data = data_addr;
bitmap->pitch = pitch + (overdraw * 2);

/* Set up line pointers */
/* we want to make some 32-bit aligned adjustment
** if we haven't been given a hardware bitmap
*/
if (false == bitmap->hardware)
{
bitmap->pitch = (bitmap->pitch + 3) & ~3;
bitmap->line[0] = (uint8 *)(((uint32)bitmap->data + overdraw + 3) & ~3);
}
else
{
bitmap->line[0] = bitmap->data + overdraw;
}

for (i = 1; i < height; i++)
bitmap->line[i] = bitmap->line[i - 1] + bitmap->pitch;

return bitmap;
}

/* Allocate and initialize a bitmap structure */
bitmap_t *bmp_create(int width, int height, int overdraw)
{
uint8 *addr;
int pitch;

pitch = width + (overdraw * 2); /* left and right */

addr = NOFRENDO_MALLOC(((pitch * height) + 3) & 0xFFFFFFF8); /* add max 32-bit aligned adjustment */
if (NULL == addr)
return NULL;

return _make_bitmap(addr, false, width, height, width, overdraw);
}

/* allocate and initialize a hardware bitmap */
bitmap_t *bmp_createhw(uint8 *addr, int width, int height, int pitch)
{
return _make_bitmap(addr, true, width, height, pitch, 0); /* zero overdraw */
}

/* Deallocate space for a bitmap structure */
void bmp_destroy(bitmap_t **bitmap)
{
if (*bitmap)
{
if ((*bitmap)->data && false == (*bitmap)->hardware)
NOFRENDO_FREE((*bitmap)->data);
NOFRENDO_FREE(*bitmap);
*bitmap = NULL;
}
}

/*
** $Log: bitmap.c,v $
** Revision 1.2 2001/04/27 14:37:11 neil
** wheeee
**
** Revision 1.1.1.1 2001/04/27 07:03:54 neil
** initial
**
** Revision 1.16 2000/11/05 16:37:18 matt
** rolled rgb.h into bitmap.h
**
** Revision 1.15 2000/10/10 13:58:13 matt
** stroustrup squeezing his way in the door
**
** Revision 1.14 2000/09/18 02:06:48 matt
** -pedantic is your friend
**
** Revision 1.13 2000/08/13 13:16:30 matt
** bugfix for alignment adjustment
**
** Revision 1.12 2000/07/24 04:31:43 matt
** pitch/data area on non-hw bitmaps get padded to 32-bit boundaries
**
** Revision 1.11 2000/07/17 01:52:27 matt
** made sure last line of all source files is a newline
**
** Revision 1.10 2000/07/09 14:43:01 matt
** pitch is now configurable for bmp_createhw()
**
** Revision 1.9 2000/07/06 17:55:57 matt
** two big bugs fixed
**
** Revision 1.8 2000/07/06 17:38:11 matt
** replaced missing string.h include
**
** Revision 1.7 2000/07/06 16:46:57 matt
** added bmp_clear() routine
**
** Revision 1.6 2000/06/26 04:56:24 matt
** minor cleanup
**
** Revision 1.5 2000/06/09 15:12:25 matt
** initial revision
**
*/
Loading