Skip to content

Commit

Permalink
Tidyup
Browse files Browse the repository at this point in the history
  • Loading branch information
ScarlettSpell committed Oct 5, 2022
1 parent f84a9a8 commit abc4ace
Show file tree
Hide file tree
Showing 71 changed files with 614 additions and 5,098 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Build
on: [pull_request, push]

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Install toolchain
uses: numworks/setup-arm-toolchain@2020-q2
- name: Install nwlink
run: npm install -g nwlink
- name: Run make build
run: make build
- name: Run make check
run: make check
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/output/
139 changes: 139 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
Q ?= @
CC = arm-none-eabi-gcc
NWLINK = nwlink
LINK_GC = 1
LTO = 1

CFLAGS += -Os -DNDEBUG
CFLAGS += $(shell $(NWLINK) eadk-cflags)
LDFLAGS = -Wl,--relocatable
LDFLAGS += -nostartfiles
LDFLAGS += --specs=nano.specs

ifeq ($(LINK_GC),1)
CFLAGS += -fdata-sections -ffunction-sections
LDFLAGS += -Wl,-e,main -Wl,-u,eadk_app_name -Wl,-u,eadk_app_icon -Wl,-u,eadk_api_level
LDFLAGS += -Wl,--gc-sections
endif

ifeq ($(LTO),1)
CFLAGS += -flto -fno-fat-lto-objects
CFLAGS += -fwhole-program
CFLAGS += -fvisibility=internal
LDFLAGS += -flinker-output=nolto-rel
endif

CFLAGS += -Isrc -Isrc/nofrendo -Isrc/nofrendo/nes -Isrc/nofrendo/libsnss -Isrc/nofrendo/cpu

objs = $(addprefix output/nofrendo/,\
bitmap.o \
config.o \
cpu/dis6502.o \
cpu/nes6502.o \
event.o \
libsnss/libsnss.o \
log.o \
mappers/map000.o \
mappers/map001.o \
mappers/map002.o \
mappers/map003.o \
mappers/map004.o \
mappers/map005.o \
mappers/map007.o \
mappers/map008.o \
mappers/map009.o \
mappers/map011.o \
mappers/map015.o \
mappers/map016.o \
mappers/map018.o \
mappers/map019.o \
mappers/map024.o \
mappers/map032.o \
mappers/map033.o \
mappers/map034.o \
mappers/map040.o \
mappers/map041.o \
mappers/map042.o \
mappers/map046.o \
mappers/map050.o \
mappers/map064.o \
mappers/map065.o \
mappers/map066.o \
mappers/map069.o \
mappers/map070.o \
mappers/map073.o \
mappers/map075.o \
mappers/map078.o \
mappers/map079.o \
mappers/map085.o \
mappers/map087.o \
mappers/map093.o \
mappers/map094.o \
mappers/map099.o \
mappers/map160.o \
mappers/map225.o \
mappers/map229.o \
mappers/map231.o \
mappers/mapvrc.o \
memguard.o \
nes/mmclist.o \
nes/nes.o \
nes/nes_mmc.o \
nes/nes_pal.o \
nes/nes_ppu.o \
nes/nes_rom.o \
nes/nesinput.o \
nes/nesstate.o \
nofrendo.o \
pcx.o \
)

ifeq ($(AUDIO),1)
objs = $(addprefix output/nofrendo/,\
sndhrdw/fds_snd.o \
sndhrdw/mmc5_snd.o \
sndhrdw/nes_apu.o \
sndhrdw/vrcvisnd.o \
)
CFLAGS += -DAUDIO=1 -Isrc/nofrendo/sndhrdw
endif

objs += $(addprefix output/, \
icon.o \
timing.o \
display.o \
sound.o \
keyboard.o \
main.o \
osd.o \
statefile_wrapper.o \
stubs.o \
)

.PHONY: build
build: output/nofrendo.nwa

.PHONY: check
check: output/nofrendo.bin

output/nofrendo.bin: output/nofrendo.nwa
@echo "NWLINK $@"
$Q $(NWLINK) nwa-bin -d src/2048.nes $< $@

output/nofrendo.nwa: $(objs)
@echo "LD $@"
$Q $(CC) $(CFLAGS) $(LDFLAGS) $^ -lm -o $@

output/%.o: src/%.c
@mkdir -p $(dir $@)
@echo "CC $^"
$Q $(CC) $(CFLAGS) -c $^ -o $@

output/icon.o: src/icon.png
@echo "ICON $<"
$(Q) $(NWLINK) png-icon-o $< $@

.PHONY: clean
clean:
@echo "CLEAN"
$Q rm -rf output
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Nofrendo

[![Build](https://github.com/nwagyu/nofrendo/actions/workflows/build.yml/badge.svg)](https://github.com/nwagyu/nofrendo/actions/workflows/build.yml)

This app is a [NES](https://en.wikipedia.org/wiki/Nintendo_Entertainment_System) emulator that runs on the [NumWorks calculator](https://www.numworks.com).

## Install the app

To install this app, you'll need to:
1. Download the latest `nofrendo.nwa` file from the [Releases](https://github.com/nwagyu/nofrendo/releases) page
2. Extract a `cartridge.nes` ROM dump from your NES cartridge, or, alternatively, use the provided `src/2048.nes` file.
2. Head to [my.numworks.com/apps](https://my.numworks.com/apps) to send the `nwa` file on your calculator along the `nes` file.

## How to use the app

The controls are pretty obvious because the NES gamepad looks a lot like the NumWorks' keyboard:

|NES controls|NumWorks|
|-|-|
|Arrow|Arrows|
|B|Back|
|A|OK|
|Select|Shift|
|Start|Backspace|

## Build the app

To build this sample app, you will need to install the [embedded ARM toolchain](https://developer.arm.com/Tools%20and%20Software/GNU%20Toolchain) and [nwlink](https://www.npmjs.com/package/nwlink).

```shell
brew install numworks/tap/arm-none-eabi-gcc node # Or equivalent on your OS
npm install -g nwlink
make clean && make build
```
File renamed without changes.
123 changes: 123 additions & 0 deletions src/display.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <eadk.h>
#undef false
#undef true
#undef bool
#include <osd.h>
#include <bitmap.h>
#include <nes.h>

#define DEFAULT_WIDTH 256
#define DEFAULT_HEIGHT NES_VISIBLE_HEIGHT

static int init(int width, int height);
static void shutdown(void);
static int set_mode(int width, int height);
static void set_palette(rgb_t *pal);
static void clear(uint8 color);
static bitmap_t *lock_write(void);
static void free_write(int num_dirties, rect_t *dirty_rects);
static void custom_blit(bitmap_t *bmp, int num_dirties, rect_t *dirty_rects);
static char fb[1]; //dummy

viddriver_t pkspDriver =
{
"video", /* 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 */
};

bitmap_t *myBitmap;

void osd_getvideoinfo(vidinfo_t *info) {
info->default_width = DEFAULT_WIDTH;
info->default_height = DEFAULT_HEIGHT;
info->driver = &pkspDriver;
}

/* 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;
}

static uint16 myPalette[256];

/* copy nes palette over to hardware */
static void set_palette(rgb_t *pal) {
for (int i = 0; i < 256; i++) {
myPalette[i] = (pal[i].b>>3)+((pal[i].g>>2)<<5)+((pal[i].r>>3)<<11);
}
}

void vid_setpalette(rgb_t *pal) {
set_palette(pal);
}

/* clear all frames to a particular color */
static void clear(uint8 color) {
}

/* acquire the directbuffer for writing */
static bitmap_t *lock_write(void) {
myBitmap = bmp_createhw((uint8*)fb, DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_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) {
uint16_t line[bmp->width];
int xoffset = (EADK_SCREEN_WIDTH - bmp->width) / 2;
int yoffset = (EADK_SCREEN_HEIGTH - bmp->height) / 2;

for(int y=0; y<bmp->height; y++) {
for(int x=0; x<bmp->width; x++) {
line[x] = myPalette[bmp->line[y][x]];
}
eadk_display_push_rect((eadk_rect_t){xoffset, y+yoffset, bmp->width, 1}, line);
}
}

void ppu_scanline_blit(uint8_t *bmp, int scanline, bool draw_flag) {
uint16_t line[NES_SCREEN_WIDTH];
const int xoffset = (EADK_SCREEN_WIDTH - NES_SCREEN_WIDTH) / 2;
const int yoffset = (EADK_SCREEN_HEIGTH - NES_SCREEN_HEIGHT) / 2;
bmp += 8;
if(draw_flag && !(scanline < 0 || scanline >= EADK_SCREEN_HEIGTH)) {
for(int x=0; x<NES_SCREEN_WIDTH; x++) {
line[x] = myPalette[*bmp++];
}
eadk_display_push_rect((eadk_rect_t){xoffset, scanline+yoffset, NES_SCREEN_WIDTH, 1}, line);
}
}
File renamed without changes
38 changes: 38 additions & 0 deletions src/keyboard.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <eadk.h>
#undef false
#undef true
#undef bool
#include <osd.h>
#include <event.h>
#include <nesinput.h>

void osd_getinput(void) {
typedef struct {
eadk_key_t key;
int event;
} key_event_mapping;
const key_event_mapping key_to_events[] = {
{eadk_key_left, event_joypad1_left},
{eadk_key_up, event_joypad1_up},
{eadk_key_down, event_joypad1_down},
{eadk_key_right, event_joypad1_right},
{eadk_key_ok, event_joypad1_b},
{eadk_key_back, event_joypad1_a},
{eadk_key_shift, event_joypad1_select},
{eadk_key_backspace, event_joypad1_start},
};

static uint64_t old_keyboard_state = 0xffffffffffffffff;
uint64_t current_keyboard_state = eadk_keyboard_scan();

for (int i=0; i<sizeof(key_to_events)/sizeof(key_to_events[0]); i++) {
bool wasUp = eadk_keyboard_key_down(old_keyboard_state, key_to_events[i].key);
bool isUp = eadk_keyboard_key_down(current_keyboard_state, key_to_events[i].key);
if (isUp != wasUp) {
event_t evt = event_get(key_to_events[i].event);
evt(isUp ? INP_STATE_MAKE : INP_STATE_BREAK);
}
}

old_keyboard_state = current_keyboard_state;
}
Loading

0 comments on commit abc4ace

Please sign in to comment.