initial commit
commit
2eaa9449a2
@ -0,0 +1,15 @@
|
||||
/*.bin
|
||||
out_*.bin
|
||||
__pycache__
|
||||
|
||||
/player/*.o
|
||||
/player/badapple
|
||||
/player/badapple.bin
|
||||
/player/badapple.mcs
|
||||
/player/data/icon.bin
|
||||
/player/data/title.txt
|
||||
|
||||
/tools/ascii2sjis
|
||||
/tools/bin2mcs
|
||||
/tools/bmp2ps1b
|
||||
/tools/mcpad
|
@ -0,0 +1,13 @@
|
||||
to build run:
|
||||
|
||||
`make clean all target=pocketstation`
|
||||
|
||||
extra options:
|
||||
- target=[pocketstation]
|
||||
specify to build for pocketstation else it builds for linux (default="")
|
||||
|
||||
- frameskip=[everynthframe]
|
||||
only display every nth frame (default=4)
|
||||
|
||||
- loop=[1|0]
|
||||
if it should loop forever (default=1)
|
Binary file not shown.
@ -0,0 +1,20 @@
|
||||
import sys
|
||||
from typing import List
|
||||
|
||||
def diff(last: List[List[bool]], current: List[List[bool]]) -> List[List[bool]]:
|
||||
out = []
|
||||
for i, row in enumerate(current):
|
||||
out.append([])
|
||||
for j, pixel in enumerate(row):
|
||||
out[i].append(pixel != last[i][j])
|
||||
return out
|
||||
|
||||
def print_frame(pixels: List[List[bool]]):
|
||||
p = "\033[H\033[J"
|
||||
for y in range(res[1]):
|
||||
for x in range(res[0]):
|
||||
p += "##" if pixels[y][x] else " "
|
||||
p += "\n"
|
||||
sys.stdout.write(p)
|
||||
|
||||
res = (32, 32)
|
@ -0,0 +1,110 @@
|
||||
import sys
|
||||
from typing import List, Tuple
|
||||
|
||||
def flatten(l):
|
||||
for i in l:
|
||||
if isinstance(i, list):
|
||||
yield from flatten(i)
|
||||
else:
|
||||
yield i
|
||||
|
||||
from common import *
|
||||
|
||||
|
||||
def encode_RLE(data: List[bool]) -> bytes:
|
||||
out = b""
|
||||
" values is a list of tuples where the first element is the count and the second is the value "
|
||||
" the count can only go upto 7 bit "
|
||||
values: List[Tuple[int,bool]] = []
|
||||
for i in range(len(data)):
|
||||
if i == 0:
|
||||
values.append((1, data[i]))
|
||||
elif data[i] != data[i-1]:
|
||||
values.append((1, data[i]))
|
||||
else:
|
||||
last = values[-1][0]
|
||||
if last < 127:
|
||||
values[-1] = (last+1, data[i])
|
||||
else:
|
||||
values.append((1, data[i]))
|
||||
|
||||
|
||||
for v in values:
|
||||
# high bit is set if value is true
|
||||
v = v[0] << 1 | int(v[1])
|
||||
out += v.to_bytes(1, "little")
|
||||
return out
|
||||
|
||||
stats = {
|
||||
"avg_frame_size": 0,
|
||||
"min_frame_size": float("inf"),
|
||||
"max_frame_size": 0,
|
||||
"total_size": 0,
|
||||
}
|
||||
|
||||
def diff_encode(frames: List[List[List[bool]]]) -> bytes:
|
||||
out = b""
|
||||
for i, frame in enumerate(frames):
|
||||
if i > 0:
|
||||
last_frame = frames[i-1]
|
||||
frame = diff(last_frame, frame)
|
||||
|
||||
o = encode_RLE(list(flatten(frame)))
|
||||
out += o
|
||||
sz_b = len(o)
|
||||
#print(f"Frame {i} size: {sz_b}")
|
||||
stats["min_frame_size"] = min(stats["min_frame_size"], sz_b)
|
||||
stats["max_frame_size"] = max(stats["max_frame_size"], sz_b)
|
||||
return out
|
||||
|
||||
def rle_encode(frames: List[List[List[bool]]]) -> bytes:
|
||||
out = b""
|
||||
for frame in frames:
|
||||
o = encode_RLE(list(flatten(frame)))
|
||||
out += o
|
||||
stats["min_frame_size"] = min(stats["min_frame_size"], len(o))
|
||||
stats["max_frame_size"] = max(stats["max_frame_size"], len(o))
|
||||
return out
|
||||
|
||||
def get_frame(f):
|
||||
pixels = []
|
||||
for y in range(res[1]):
|
||||
b = f.read(4)
|
||||
if len(b) < 4:
|
||||
return None
|
||||
row = [ int(a) == 1 for a in bin(int.from_bytes(b, "little"))[2:].zfill(32)]
|
||||
pixels.append(row)
|
||||
return pixels
|
||||
|
||||
|
||||
def encode():
|
||||
f = open("badapple_input.bin", "rb")
|
||||
frames = []
|
||||
i = 0
|
||||
while True:
|
||||
i += 1
|
||||
pixels = get_frame(f)
|
||||
if not pixels:
|
||||
break
|
||||
if i % frameskip == 0:
|
||||
frames.append(pixels)
|
||||
stats["frame_count"] = len(frames)
|
||||
|
||||
with open("out_diff.bin", "wb") as fo:
|
||||
o = diff_encode(frames)
|
||||
stats["avg_frame_size"] = len(o) / len(frames)
|
||||
stats["total_size"] = len(o)
|
||||
fo.write(o)
|
||||
print("diff", stats)
|
||||
|
||||
with open("out_rle.bin", "wb") as fo:
|
||||
o = rle_encode(frames)
|
||||
stats["avg_frame_size"] = len(o) / len(frames)
|
||||
stats["total_size"] = len(o)
|
||||
fo.write(o)
|
||||
print("rle", stats)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
frameskip = int(sys.argv[1])
|
||||
encode()
|
@ -0,0 +1,37 @@
|
||||
import time
|
||||
from typing import IO
|
||||
from common import *
|
||||
|
||||
|
||||
def decode_frame(f: IO[bytes], last_frame: list[list[bool]]) -> list[list[bool]]:
|
||||
pixels = []
|
||||
while len(pixels) < res[0]*res[1]:
|
||||
count = int.from_bytes(f.read(1), "little")
|
||||
# high bit stores value
|
||||
val = bool(count & 1)
|
||||
cnt = count >> 1
|
||||
for _ in range(cnt):
|
||||
pixels.append(val)
|
||||
# reshape to res
|
||||
pixels = [pixels[i:i+res[0]] for i in range(0, len(pixels), res[0])]
|
||||
|
||||
# apply diff
|
||||
if last_frame:
|
||||
pixels = diff(last_frame, pixels)
|
||||
return pixels
|
||||
|
||||
def run_encoded():
|
||||
f = open("out_diff.bin", "rb")
|
||||
last_frame = None
|
||||
while True:
|
||||
t1 = time.time()
|
||||
pixels = decode_frame(f, last_frame)
|
||||
if len(pixels) == 0:
|
||||
break
|
||||
last_frame = pixels
|
||||
print_frame(pixels)
|
||||
t2 = time.time()
|
||||
time.sleep(1/24 - (t2-t1))
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_encoded()
|
@ -0,0 +1,100 @@
|
||||
frameskip := 4
|
||||
loop := 1
|
||||
RLE := 1
|
||||
name = badapple
|
||||
|
||||
DEFINES += -DFRAMESKIP=$(frameskip)
|
||||
|
||||
ifneq ($(loop),1)
|
||||
else
|
||||
DEFINES += -DLOOP=$(loop)
|
||||
endif
|
||||
|
||||
ifneq ($(RLE),1)
|
||||
input_type = diff
|
||||
else
|
||||
DEFINES += -DRLE
|
||||
input_type = rle
|
||||
endif
|
||||
|
||||
|
||||
LDFLAGS =
|
||||
CFLAGS = -Wl,--gc-sections -nostartfiles -s -static -nostdlib -Os -ffunction-sections -fdata-sections
|
||||
|
||||
|
||||
# if pocketstation
|
||||
ifeq ($(target),pocketstation)
|
||||
POCKETSTATION = 1
|
||||
CC = arm-none-eabi-gcc
|
||||
LD = arm-none-eabi-ld
|
||||
OBJCOPY = arm-none-eabi-objcopy
|
||||
AS = arm-none-eabi-as
|
||||
|
||||
LDFLAGS += -Tldscript
|
||||
CFLAGS += -march=armv4 -mtune=arm7tdmi
|
||||
COPYFLAGS = -I binary -O elf32-littlearm
|
||||
|
||||
DEFINES += -D__POCKETSTATION__
|
||||
extra_objects = head.o
|
||||
|
||||
else ifeq ($(target),)
|
||||
CC = gcc
|
||||
LD = gcc
|
||||
OBJCOPY = objcopy
|
||||
AS = as
|
||||
|
||||
COPYFLAGS = -B i386 -I binary -O elf64-x86-64
|
||||
DEFINES += -D__LINUX__
|
||||
else
|
||||
$(error "unknown target")
|
||||
endif
|
||||
|
||||
|
||||
all: $(name)
|
||||
|
||||
ifdef POCKETSTATION
|
||||
all: $(name).mcs
|
||||
|
||||
$(name).mcs: $(name).bin tools
|
||||
../tools/bin2mcs BESCEDP-00000BADAPPLE0 $< $@
|
||||
|
||||
$(name).bin: $(name) tools
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
../tools/mcpad $@
|
||||
|
||||
head.o: head.s data/title.txt data/icon.bin
|
||||
endif
|
||||
|
||||
$(name): player.o badapple_$(input_type).o $(extra_objects)
|
||||
$(LD) $(LDFLAGS) $^ -o $@
|
||||
|
||||
player.o: player.c
|
||||
$(CC) -c $(CFLAGS) $(DEFINES) player.c -o player.o
|
||||
|
||||
|
||||
badapple_$(input_type).o: out_$(input_type).bin
|
||||
cp $< badapple_$(input_type).bin
|
||||
$(OBJCOPY) $(COPYFLAGS) badapple_$(input_type).bin $@
|
||||
rm badapple_$(input_type).bin
|
||||
|
||||
out_$(input_type).bin:
|
||||
cd ../encoder && python3 encode.py $(frameskip)
|
||||
cp ../encoder/out_$(input_type).bin .
|
||||
|
||||
|
||||
tools:
|
||||
cd ../tools && make
|
||||
|
||||
|
||||
data/title.txt: tools
|
||||
../tools/ascii2sjis $(name) $@
|
||||
|
||||
data/icon.bin: ../icon.BMP tools
|
||||
../tools/bmp_to_1bit.py $< icon1bit.bmp
|
||||
../tools/bmp2ps1b b icon1bit.bmp
|
||||
rm icon1bit.bmp
|
||||
mv icon1bit.bin $@
|
||||
|
||||
clean:
|
||||
rm -f *.o $(name) $(name).bin $(name).mcs out_*.bin data/icon.bin data/title.txt
|
||||
cd ../tools && make clean
|
Binary file not shown.
@ -0,0 +1,78 @@
|
||||
.text
|
||||
.code 32
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
.ascii "SC"
|
||||
.byte 0x11
|
||||
.byte 1 // Number of memory card blocks (use "mcpad" tool for auto-adjust)
|
||||
|
||||
// Title 32*2 Shift-JIS zero padded (use "ascii2sjis" tool to generate this file)
|
||||
.include "data/title.txt"
|
||||
.space 12
|
||||
|
||||
.hword 1 // Number of File Viewer Mono Icon Frames
|
||||
.ascii "MCX0"
|
||||
.byte 1 // Number of entries in Executable Mono Icon List
|
||||
.byte 0 // No Function Table
|
||||
.word 0
|
||||
.word _progstart
|
||||
|
||||
IconPS: .incbin "data/psicon.bin" // 16*word Palette + 16x16 4bits Icon
|
||||
IconPK: .incbin "data/icon.bin" // File Viewer Mono Icon 32x32
|
||||
|
||||
.hword 1 // Number of Executable Mono Icon
|
||||
.hword 1 // Icon Anim Speed
|
||||
.word IconPK // Pointer to the same File Viewer Mono Icon
|
||||
|
||||
_progstart:
|
||||
b main
|
||||
|
||||
//----------------------------------------
|
||||
// Bios Calls
|
||||
|
||||
.globl SetCallbacks
|
||||
SetCallbacks:
|
||||
swi 1
|
||||
mov pc, lr
|
||||
|
||||
.globl SetCpuSpeed
|
||||
SetCpuSpeed:
|
||||
swi 4
|
||||
mov pc, lr
|
||||
|
||||
.globl PrepareExecute
|
||||
PrepareExecute:
|
||||
swi 8
|
||||
mov pc, lr
|
||||
|
||||
.globl DoExecute
|
||||
DoExecute:
|
||||
swi 9
|
||||
|
||||
.globl SetComOnOff
|
||||
SetComOnOff:
|
||||
swi 17
|
||||
mov pc, lr
|
||||
|
||||
.globl GetDirIndex
|
||||
GetDirIndex:
|
||||
swi 22
|
||||
mov pc, lr
|
||||
|
||||
.globl IntIRQ
|
||||
IntIRQ:
|
||||
stmdb sp!,{r2-r3,lr}
|
||||
bl IRQ_Handler
|
||||
ldmia sp!,{r2-r3,pc}
|
||||
|
||||
.globl IntFIQ
|
||||
IntFIQ:
|
||||
stmdb sp!,{r2-r3,lr}
|
||||
bl FIQ_Handler
|
||||
ldmia sp!,{r2-r3,pc}
|
||||
|
||||
|
||||
//----------------------------------------
|
||||
// User Data
|
||||
.end
|
@ -0,0 +1,63 @@
|
||||
OUTPUT_ARCH(arm)
|
||||
MEMORY
|
||||
{
|
||||
ram : o = 0x00000204, l = 0x5fc
|
||||
rom : o = 0x02000000, l = 0x1E000
|
||||
}
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
*(.strings)
|
||||
*(.rodata)
|
||||
*(.rdata)
|
||||
_etext = . ;
|
||||
} > rom
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
*all.rodata*(*)
|
||||
*(.roda)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r*)
|
||||
SORT(CONSTRUCTORS)
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} > rom
|
||||
.tors :
|
||||
{
|
||||
___ctors = . ;
|
||||
*(.ctors)
|
||||
___ctors_end = . ;
|
||||
___dtors = . ;
|
||||
*(.dtors)
|
||||
___dtors_end = . ;
|
||||
} > rom
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
_edata = . ;
|
||||
} > rom
|
||||
.glue_7 :
|
||||
{
|
||||
*(.glue_7)
|
||||
_glut_7 = . ;
|
||||
} > rom
|
||||
.glue_7t :
|
||||
{
|
||||
*(.glue_7t)
|
||||
_glut_7t = . ;
|
||||
} > rom
|
||||
.buffer :
|
||||
{
|
||||
*(.buffer)
|
||||
_buffer = . ;
|
||||
} > rom
|
||||
.bss :
|
||||
{
|
||||
_bss_start = . ;
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
_end = .;
|
||||
} > ram
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
#include <stdint.h>
|
||||
|
||||
const int res = 32;
|
||||
|
||||
#define setbit(arr, i) arr[i/8] |= (1 << (i%8))
|
||||
#define clrbit(arr, i) arr[(i)/8] &= ~(1 << ((i) % 8))
|
||||
#define flpbit(arr, i) arr[(i)/8] ^= 1 << ((i) % 8)
|
||||
#define getbit(arr, i) arr[(i)/8] & (1 << ((i) % 8))
|
||||
|
||||
#ifdef RLE
|
||||
#define NAME_BIN "badapple_rle_bin"
|
||||
#else
|
||||
#define NAME_BIN "badapple_diff_bin"
|
||||
#endif
|
||||
|
||||
extern uint8_t _binary_badapple_bin_start[] asm("_binary_" NAME_BIN "_start");
|
||||
extern uint8_t _binary_badapple_bin_end[] asm("_binary_" NAME_BIN "_end");
|
||||
|
||||
static uint8_t screen[0x80];
|
||||
|
||||
#ifdef __LINUX__
|
||||
#include <unistd.h>
|
||||
#define clear_screen "\033[2J\033[1;1H"
|
||||
|
||||
void display() {
|
||||
char buf[res*res*2 + res];
|
||||
char* p = buf;
|
||||
for (int i = 0; i < res; i++) {
|
||||
for (int j = 0; j < res; j++) {
|
||||
uint8_t on = getbit(screen, (i * res) + j);
|
||||
*p++ = on ? '#' : ' ';
|
||||
*p++ = on ? '#' : ' ';
|
||||
}
|
||||
*p = '\n';
|
||||
p++;
|
||||
}
|
||||
write(1, clear_screen, sizeof(clear_screen)-1);
|
||||
write(1, buf, sizeof(buf));
|
||||
// ""vsync"""
|
||||
usleep(16666*FRAMESKIP);
|
||||
}
|
||||
#define ROMByteAccess(addr) *(uint8_t*)(addr)
|
||||
#endif
|
||||
|
||||
#ifdef __POCKETSTATION__
|
||||
#define FPS 24
|
||||
#define CLOCK_SPEED CLOCK_4M
|
||||
#include "pocketlib.h"
|
||||
|
||||
static void display() {
|
||||
// ????
|
||||
for(int i = 0; i<FRAMESKIP*2; i++) VSync();
|
||||
uint32_t *src = (uint32_t*)screen;
|
||||
volatile unsigned int *dst = LCD_VRAM_ADRS;
|
||||
int i = 32;
|
||||
while (i--) {*dst++ = *src++;}
|
||||
}
|
||||
|
||||
uint8_t ROMByteAccess(unsigned char *addr)
|
||||
{
|
||||
uint16_t data = *(uint16_t*)(((uint32_t)addr) & ~1);
|
||||
|
||||
if (((uint32_t)addr) & 1)
|
||||
return (data >> 8);
|
||||
return (data & 0xFF);
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(void) {
|
||||
#ifdef __POCKETSTATION__
|
||||
PocketInit();
|
||||
#endif
|
||||
|
||||
do {
|
||||
// read all frames
|
||||
uint8_t* p = _binary_badapple_bin_start;
|
||||
while(p < _binary_badapple_bin_end) {
|
||||
// read a frame
|
||||
uint16_t px = 0;
|
||||
while(px < res*res && p < _binary_badapple_bin_end) {
|
||||
uint8_t value = ROMByteAccess(p++);
|
||||
uint8_t changed = value & 1;
|
||||
uint8_t count = value >> 1;
|
||||
|
||||
#ifdef RLE
|
||||
for(int i = px; i < count+px; i++) {
|
||||
if(changed) setbit(screen, i);
|
||||
else clrbit(screen, i);
|
||||
}
|
||||
#else // diff + rle
|
||||
if(changed) {
|
||||
for (int i = px; i < px+count; i++) flpbit(screen, i);
|
||||
}
|
||||
#endif
|
||||
px += count;
|
||||
}
|
||||
display();
|
||||
}
|
||||
#ifdef LOOP
|
||||
} while(1);
|
||||
#else
|
||||
} while(0);
|
||||
#endif
|
||||
|
||||
#ifdef __POCKETSTATION__
|
||||
PocketExit();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,218 @@
|
||||
/****************************************/
|
||||
/* PocketStation Lib - by Orion_ [2013] */
|
||||
/****************************************/
|
||||
// Based on Miko Hoshina & Martin Korth work.
|
||||
// If you use it, please give credits !
|
||||
// v3.6
|
||||
|
||||
// Optional Functions, don't define this in your main .c file do reduce size
|
||||
//#define USE_SPRITE
|
||||
//#define USE_RANDOM
|
||||
//#define USE_SOUND
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void*)0)
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_SPEED
|
||||
#define CLOCK_SPEED CLOCK_4M
|
||||
#endif
|
||||
|
||||
#ifndef FPS
|
||||
#define FPS 64
|
||||
#endif
|
||||
|
||||
#ifndef SOUND_FREQ
|
||||
#define SOUND_FREQ 4000 // If 8000Hz, then use CLOCK_8M !
|
||||
#endif
|
||||
|
||||
/**/
|
||||
|
||||
#define PAD_BUTTON 0x1
|
||||
#define PAD_RIGHT 0x2
|
||||
#define PAD_LEFT 0x4
|
||||
#define PAD_DOWN 0x8
|
||||
#define PAD_UP 0x10
|
||||
|
||||
#define PAD_STATUS ((IRQ_STATUS_RAW) & 0x1F)
|
||||
|
||||
int PadOnRelease, PadOnPress;
|
||||
|
||||
/**/
|
||||
|
||||
#define LCD_ON 0x40
|
||||
#define LCD_OFF 0x00
|
||||
#define LCD_64HZ 0x10
|
||||
#define LCD_32HZ 0x20
|
||||
#define LCD_16HZ 0x30
|
||||
#define LCD_CPEN 0x08
|
||||
|
||||
#define LCD_MODE *((volatile unsigned int *)0xD000000)
|
||||
#define LCD_VRAM(_line_) *((volatile unsigned int *)(0xD000100+(_line_ << 2)))
|
||||
#define LCD_VRAM_ADRS (volatile unsigned int *)0xD000100
|
||||
|
||||
/**/
|
||||
|
||||
#define CLOCK_62_5K 0x1
|
||||
#define CLOCK_125K 0x2
|
||||
#define CLOCK_250K 0x3
|
||||
#define CLOCK_500K 0x4
|
||||
#define CLOCK_1M 0x5
|
||||
#define CLOCK_2M 0x6
|
||||
#define CLOCK_4M 0x7
|
||||
#define CLOCK_8M 0x8
|
||||
|
||||
/**/
|
||||
|
||||
#define TIMER0_START() *((volatile unsigned int *)(0xA800008)) |= 0x4
|
||||
#define TIMER1_START() *((volatile unsigned int *)(0xA800018)) |= 0x4
|
||||
#define TIMER2_START() *((volatile unsigned int *)(0xA800028)) |= 0x4
|
||||
#define TIMER0_STOP() *((volatile unsigned int *)(0xA800008)) &= ~0x4
|
||||
#define TIMER1_STOP() *((volatile unsigned int *)(0xA800018)) &= ~0x4
|
||||
#define TIMER2_STOP() *((volatile unsigned int *)(0xA800028)) &= ~0x4
|
||||
#define TIMER0_SETCOUNT(_x_) *((volatile unsigned int *)(0xA800000)) = (_x_)
|
||||
#define TIMER1_SETCOUNT(_x_) *((volatile unsigned int *)(0xA800010)) = (_x_)
|
||||
#define TIMER2_SETCOUNT(_x_) *((volatile unsigned int *)(0xA800020)) = (_x_)
|
||||
|
||||
/**/
|
||||
|
||||
#define FIQ_COMM 0x40
|
||||
#define IRQ_TIMER0 0x80
|
||||
#define IRQ_TIMER1 0x100
|
||||
#define IRQ_RTC 0x200
|
||||
#define IRQ_BATTERY 0x400
|
||||
#define IRQ_PSCOMM 0x800
|
||||
#define IRQ_INFRARED 0x1000
|
||||
#define FIQ_TIMER2 0x2000
|
||||
|
||||
#define IRQ_STATUS *((volatile unsigned int *)(0xA000000))
|
||||
#define IRQ_STATUS_RAW *((volatile unsigned int *)(0xA000004))
|
||||
#define IRQ_ENABLE *((volatile unsigned int *)(0xA000008))
|
||||
#define IRQ_DISABLE *((volatile unsigned int *)(0xA00000c))
|
||||
#define IRQ_CLEAR *((volatile unsigned int *)(0xA000010))
|
||||
|
||||
#define IRQ_DISABLE_ALL() IRQ_DISABLE = 0x3FFF;
|
||||
|
||||
/**/
|
||||
|
||||
#define IOCTL_CONFIG *((volatile unsigned int *)0xD800000)
|
||||
#define IOCTL_OFF *((volatile unsigned int *)0xD800004)
|
||||
#define IOCTL_ON *((volatile unsigned int *)0xD800008)
|
||||
#define IOCTL_DAC *((volatile unsigned int *)0xD800010)
|
||||
#define IOCTL_DASOUND *((volatile unsigned int *)0xD800014)
|
||||
#define IOCTL_BATTERY *((volatile unsigned int *)0xD800020)
|
||||
|
||||
#define IOCTL_LED 0x02
|
||||
#define IOCTL_SPEAKER 0x20
|
||||
#define IOCTL_IRDA 0x40
|
||||
|
||||
|
||||
/****************************************/
|
||||
// From header.S
|
||||
|
||||
// Bios Calls
|
||||
void *SetCallbacks(int index, void (*function));
|
||||
int SetCpuSpeed(int speed);
|
||||
int PrepareExecute(int flag, int dir_index, int param);
|
||||
void DoExecute(int snapshot_flag);
|
||||
void SetComOnOff(int flag);
|
||||
int GetDirIndex(void);
|
||||
|
||||
// IRQ/FIQ Asm
|
||||
void IntIRQ(void);
|
||||
void IntFIQ(void);
|
||||
|
||||
void (*UserIRQ)(void);
|
||||
int (*UserFIQ)(void); // Return 1 to Skip Library Sound Processing, else return 0
|
||||
|
||||
|
||||
/****************************************/
|
||||
// IRQ/Timer0 Handler (for VSync)
|
||||
|
||||
volatile int VCount;
|
||||
|
||||
void IRQ_Handler(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = IRQ_STATUS;
|
||||
status &= IRQ_ENABLE;
|
||||
status &= ~(FIQ_TIMER2 | FIQ_COMM); // Clear FIQ Bits
|
||||
|
||||
if (status & IRQ_TIMER0)
|
||||
VCount++;
|
||||
|
||||
if (UserIRQ)
|
||||
UserIRQ();
|
||||
|
||||
IRQ_CLEAR = status;
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
// FIQ/Timer2 Handler (for Sound)
|
||||
|
||||
void FIQ_Handler(void)
|
||||
{
|
||||
IRQ_CLEAR = FIQ_TIMER2;
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
// Sync Functions
|
||||
|
||||
void VSync()
|
||||
{
|
||||
register int cnt = VCount;
|
||||
register int PadState = PAD_STATUS;
|
||||
|
||||
PadOnRelease = PadState;
|
||||
PadOnRelease ^= PadOnPress;
|
||||
PadOnRelease &= PadOnPress;
|
||||
PadOnPress = PadState;
|
||||
|
||||
while (VCount == cnt); // Wait For IRQ Timer0
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
// Init, need to be called at first !
|
||||
|
||||
void PocketInit(void)
|
||||
{
|
||||
SetCpuSpeed(CLOCK_SPEED);
|
||||
IRQ_DISABLE_ALL();
|
||||
|
||||
UserIRQ = NULL;
|
||||
UserFIQ = NULL;
|
||||
|
||||
VCount = 0;
|
||||
PadOnRelease = 0;
|
||||
PadOnPress = 0;
|
||||
|
||||
SetCallbacks(1, IntIRQ); // VSync Interrupt
|
||||
SetCallbacks(2, IntFIQ); // Audio Interrupt
|
||||
|
||||
IRQ_CLEAR = IRQ_TIMER0 | FIQ_TIMER2;
|
||||
IRQ_ENABLE = IRQ_TIMER0 | FIQ_TIMER2;
|
||||
|
||||
// Start VSync Timer
|
||||
TIMER0_SETCOUNT((15625 << CLOCK_SPEED) / FPS);
|
||||
TIMER0_START();
|
||||
|
||||
while (PAD_STATUS & PAD_BUTTON); // Wait for Button Release (Button pressed when comming from Menu)
|
||||
}
|
||||
|
||||
|
||||
/****************************************/
|
||||
// Exit, need to be called to exit app !
|
||||
|
||||
void PocketExit(void)
|
||||
{
|
||||
SetComOnOff(0);
|
||||
TIMER0_STOP();
|
||||
TIMER2_STOP();
|
||||
IRQ_DISABLE_ALL();
|
||||
IRQ_ENABLE = IRQ_RTC | IRQ_PSCOMM;
|
||||
PrepareExecute(1, 0, GetDirIndex() | 0x30); // Return to GUI on our Program Icon
|
||||
DoExecute(0);
|
||||
}
|
||||
|
||||
/****************************************/
|
@ -0,0 +1,9 @@
|
||||
all: ascii2sjis bin2mcs bmp2ps1b mcpad
|
||||
|
||||
ascii2sjis: ascii2sjis.c
|
||||
bin2mcs: bin2mcs.c
|
||||
bmp2ps1b: bmp2ps1b.c
|
||||
mcpad: mcpad.c
|
||||
|
||||
clean:
|
||||
rm -f ascii2sjis bin2mcs bmp2ps1b mcpad
|
@ -0,0 +1,105 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char ShiftJISpunc[] = ",.:;?!^_-/\\~|()[]{}+-=<>'\"$£%#&*@";
|
||||
unsigned char ShiftJISpuncCode[] = {0x43,0x44,0x46,0x47,0x48,0x49,0x4F,0x51,0x5D,0x5E,0x5F,0x60,0x62,0x69,0x6A,0x6D,0x6E,0x6F,0x70,0x7B,0x7C,0x81,0x83,0x84,0x8C,0x8D,0x90,0x92,0x93,0x94,0x95,0x96,0x97};
|
||||
|
||||
void ASCII2ShiftJIS(char *src, unsigned char *dst)
|
||||
{
|
||||
while (*src)
|
||||
{
|
||||
if (*src == ' ')
|
||||
{
|
||||
*dst++ = 0x81;
|
||||
*dst++ = 0x40;
|
||||
}
|
||||
else if ((*src >= '0') && (*src <= '9'))
|
||||
{
|
||||
*dst++ = 0x82;
|
||||
*dst++ = 0x4F + ((*src) - '0');
|
||||
}
|
||||
else if ((*src >= 'A') && (*src <= 'Z'))
|
||||
{
|
||||
*dst++ = 0x82;
|
||||
*dst++ = 0x60 + ((*src) - 'A');
|
||||
}
|
||||
else if ((*src >= 'a') && (*src <= 'z'))
|
||||
{
|
||||
*dst++ = 0x82;
|
||||
*dst++ = 0x81 + ((*src) - 'a');
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(ShiftJISpuncCode); i++)
|
||||
if (*src == ShiftJISpunc[i])
|
||||
{
|
||||
*dst++ = 0x81;
|
||||
*dst++ = ShiftJISpuncCode[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
src++;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char buffer[64];
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *f;
|
||||
int size;
|
||||
|
||||
printf("ASCII2ShiftJIS for PocketStation Lib - by Orion_ [2013]\n\n");
|
||||
|
||||
if (argc > 2)
|
||||
{
|
||||
size = strlen(argv[1]);
|
||||
if (size > 32)
|
||||
{
|
||||
printf("Title too long (must be <= 32)\n");
|
||||
return (-1);
|
||||
}
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
ASCII2ShiftJIS(argv[1], buffer);
|
||||
|
||||
f = fopen(argv[2], "wb");
|
||||
if (!f)
|
||||
{
|
||||
printf("Cannot create file %s\n", argv[2]);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// Title
|
||||
fprintf(f, "\t/* %s */\r\n", argv[1]); // Just to keep a record of the Original Title :)
|
||||
fprintf(f, "\t.ascii\t\"");
|
||||
fwrite(buffer, 1, size*2, f);
|
||||
fprintf(f, "\"\r\n");
|
||||
|
||||
// Padding
|
||||
if (size < 32)
|
||||
{
|
||||
fprintf(f, "\t.hword\t");
|
||||
size = 32 - size;
|
||||
while (size)
|
||||
{
|
||||
fprintf(f, "0");
|
||||
size--;
|
||||
if (size)
|
||||
fprintf(f, ",");
|
||||
}
|
||||
fprintf(f, "\r\n");
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Usage: ascii2sjis ASCII_Title file.sjis\n\n");
|
||||
printf("Ex: ascii2sjis \"Test Program\" title.sjis\n\n");
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
unsigned char data[128*1025];
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *f;
|
||||
int size, i;
|
||||
|
||||
printf("MemoryCard BIN TO MCS - by Orion_ [2013]\n\n");
|
||||
|
||||
if (argc > 3)
|
||||
{
|
||||
f = fopen(argv[2], "rb");
|
||||
if (f)
|
||||
{
|
||||
memset(data, 0, sizeof(data));
|
||||
size = fread(&data[128], 1, sizeof(data)-128, f);
|
||||
|
||||
if ((data[128] == 'S') && (data[129] == 'C'))
|
||||
{
|
||||
fclose(f);
|
||||
|
||||
size = (size + 8191) >> 13; // One Block = 8k
|
||||
data[128+3] = size; // Adjust Block Number
|
||||
size <<= 13; // Pad to 8k
|
||||
|
||||
f = fopen(argv[3], "wb");
|
||||
if (f)
|
||||
{
|
||||
// Generate MCS header
|
||||
data[0] = 0x51;
|
||||
data[4] = (size >> 0) & 0xFF;
|
||||
data[5] = (size >> 8) & 0xFF;
|
||||
data[6] = (size >> 16) & 0xFF;
|
||||
data[7] = (size >> 24) & 0xFF;
|
||||
data[8] = 1; // next block
|
||||
strncpy(&data[10], argv[1], 20);
|
||||
|
||||
for (i = 0; i < 127; i++)
|
||||
data[127] ^= data[i];
|
||||
|
||||
fwrite(data, 1, 128+size, f);
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
printf("Cannot create output file\n");
|
||||
}
|
||||
else
|
||||
printf("Bad MemoryCard BIN file format\n");
|
||||
}
|
||||
else
|
||||
printf("Cannot load input file\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Usage: bin2mcs FileID file.bin file.mcs\n\n");
|
||||
printf("FileID Description: BcSlCTxCCCCCFILENAME (20 char max)\n");
|
||||
printf(" Bc -> BI = Japan, BA = America, BE = Europe\n");
|
||||
printf(" Sl -> SC = Sony Computer, SL = Sony Licensed\n");
|
||||
printf(" C -> P = Japan, U = America, E = Europe\n");
|
||||
printf(" T -> S = Game, D = Demo, M = ?\n");
|
||||
printf(" x -> - = Normal Save, P = PocketStation\n");
|
||||
printf(" CCCCC -> Game Digit Code\n");
|
||||
printf(" FILENAME -> This Save Specific Filename\n");
|
||||
printf("\nFileID Example:\n");
|
||||
printf("BISLPS-00000GAMENAME Sony Licensed Japan, Game Code:00000 Filename: GAMENAME\n");
|
||||
printf("BASCUS-21042SAVEFILE Sony Computer America, Game Code:21042 Filename: SAVEFILE\n");
|
||||
printf("BESCES-88888FILENAME Sony Computer Europe, Game Code:88888 Filename: FILENAME\n");
|
||||
printf("BESLESP00000MINIGAME Sony Licensed Europe, PocketStation Filename: MINIGAME\n\n");
|
||||
getchar();
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *in, *out;
|
||||
unsigned short x, y;
|
||||
unsigned int a, b;
|
||||
char n[255], *p;
|
||||
int i, j, k, s;
|
||||
|
||||
printf("2 Colors BMP - to - PocketStation Binary data -- by Orion_ [2007-2013]\n\n");
|
||||
s = 0;
|
||||
|
||||
if (argc > 2)
|
||||
{
|
||||
if ((argv[1][0] == 's') || (argv[1][0] == 'h') || (argv[1][0] == 'b'))
|
||||
{
|
||||
in = fopen(argv[2], "rb");
|
||||
if (in)
|
||||
{
|
||||
strcpy(n, argv[2]);
|
||||
p = strstr(n, ".bmp");
|
||||
if (p)
|
||||
{
|
||||
if (argv[1][0] == 'b')
|
||||
{
|
||||
strcpy(p + 1, "bin");
|
||||
out = fopen(n, "wb");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(p + 1, argv[1]);
|
||||
out = fopen(n, "w");
|
||||
}
|
||||
if (out)
|
||||
{
|
||||
fseek(in,18,SEEK_SET);
|
||||
fread(&x,2,1,in);
|
||||
x /= 32;
|
||||
if (x >= 1)
|
||||
{
|
||||
fseek(in,22,SEEK_SET);
|
||||
fread(&y,2,1,in);
|
||||
*(p - 2) = '\0';
|
||||
if (argv[1][0] == 'h')
|
||||
fprintf(out, "const u32\t%s_gfx[] = {\n", n);
|
||||
for (k = 0; k < y; k++)
|
||||
{
|
||||
fseek(in,-((k*x*4)+x*4),SEEK_END);
|
||||
if (argv[1][0] == 's')
|
||||
fprintf(out, "\t.word\t");
|
||||
for (i = 0; i < x; i++)
|
||||
{
|
||||
fread(&a,4,1,in);
|
||||
b = 0;
|
||||
for (j = 0; j < 32; j++)
|
||||
b |= (((a >> (31-j)) & 1) << j);
|
||||
b ^= 0xFFFFFFFF;
|
||||
b = (b >> 24) | (((b >> 16) & 0xFF) << 8) | (((b >> 8) & 0xFF) << 16) | ((b & 0xFF) << 24);
|
||||
if (argv[1][0] == 'b')
|
||||
fwrite(&b, 1, 4, out);
|
||||
else
|
||||
fprintf(out, "0x%x", b);
|
||||
if ((argv[1][0] == 'h') || ((argv[1][0] == 's') && (i != x - 1)))
|
||||
fprintf(out, ",");
|
||||
}
|
||||
if (argv[1][0] != 'b')
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
if (argv[1][0] == 'h')
|
||||
fprintf(out, "};\n");
|
||||
s = 1;
|
||||
}
|
||||
else
|
||||
printf("Width must be at least 32\n");
|
||||
}
|
||||
else
|
||||
printf("Cannot create output file\n");
|
||||
}
|
||||
else
|
||||
printf("Bad filename\n");
|
||||
}
|
||||
else
|
||||
printf("Cannot load input file\n");
|
||||
}
|
||||
else
|
||||
printf("First argument must be 'h', 's', or 'b' (H = C Header File, S = ASM File, B = Binary File)\n");
|
||||
}
|
||||
|
||||
if (s)
|
||||
printf("done...\n");
|
||||
else
|
||||
{
|
||||
printf("\nUsage: bmp2ps1b [h|s|b] file.bmp\n\n");
|
||||
printf("First argument must be 'h', 's', or 'b' (H = C Header File, S = ASM File, B = Binary File)\n");
|
||||
printf("BMP MUST BE 1BITS !! (Black and White 2 colors palette)\n\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
#!/bin/python3
|
||||
import sys
|
||||
from PIL import Image
|
||||
|
||||
img = Image.open(sys.argv[1])
|
||||
img = img.convert("1", dither=Image.Dither.NONE)
|
||||
img = img.resize((32,32), Image.Resampling.NEAREST)
|
||||
img.save(sys.argv[2])
|
@ -0,0 +1,51 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
unsigned char data[128*1024];
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *f;
|
||||
int size, osize;
|
||||
|
||||
printf("MemoryCard Block Padder & Adjust - by Orion_ [2013]\n\n");
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
f = fopen(argv[1], "rb");
|
||||
if (f)
|
||||
{
|
||||
memset(data, 0, sizeof(data));
|
||||
osize = size = fread(data, 1, sizeof(data), f);
|
||||
|
||||
if ((data[0] == 'S') && (data[1] == 'C'))
|
||||
{
|
||||
fclose(f);
|
||||
|
||||
size = (size + 8191) >> 13; // One Block = 8k
|
||||
data[3] = size; // Adjust Block Number
|
||||
size <<= 13; // Pad to 8k
|
||||
|
||||
f = fopen(argv[1], "wb");
|
||||
if (f)
|
||||
{
|
||||
fwrite(data, 1, size, f);
|
||||
fclose(f);
|
||||
printf("Free Space: %d\n", size - osize);
|
||||
printf("%d Block(s)\n", data[3]);
|
||||
}
|
||||
else
|
||||
printf("Cannot create output file\n");
|
||||
}
|
||||
else
|
||||
printf("Bad MemoryCard file format\n");
|
||||
}
|
||||
else
|
||||
printf("Cannot load input file\n");
|
||||
}
|
||||
else
|
||||
printf("Usage: mcpad mcfile.bin\n\n");
|
||||
|
||||
return (0);
|
||||
}
|
Loading…
Reference in New Issue