Adding a Title Screen

This commit is contained in:
Christophe Meneboeuf 2016-12-13 01:45:27 +01:00
parent 124a858e4d
commit 117806bc32
20 changed files with 98 additions and 147 deletions

1
.gitignore vendored Normal file → Executable file
View File

@ -3,3 +3,4 @@
*.o
*.map
*.bak
*.s

0
COPYING Normal file → Executable file
View File

2
Makefile Normal file → Executable file
View File

@ -19,7 +19,7 @@ linux: $(LINUX_SRC)
$(LINUX_CC) -o $(LINUX_OUT) $? $(LINUX_CFLAGS)
apple2: $(APPLE2_SRC)
$(APPLE2_CL) -m $(APPLE2_MAP) -o $(APPLE2_OUT) $? $(APPLE2_CFLAGS)
$(APPLE2_CL) -m $(APPLE2_MAP) -o $(APPLE2_OUT) $? $(APPLE2_CFLAGS) -C src/game-of-life.cfg
apple2-asm: $(APPLE2_SRC)
$(APPLE2_CC) $(APPLE2_CFLAGS) -r -T $?

7
README.md Normal file → Executable file
View File

@ -22,6 +22,13 @@ Two binaries will be produced.
Run the *add-to-disk.sh* script.
**Title screen**
The title screen art is located in the *assets* folder. It has to be
manually loaded on the disk image using the *AppleCommander's GUI*, for the
command line loads a corrupted file!
This screen was converted from a PNG using [*Rgb2Hires*](https://github.com/Pixinn/Rgb2Hires).
---
For more information, you can refer to these posts on [my blog](https://www.xtof/info/blog/).

BIN
assets/gol.screen Executable file

Binary file not shown.

0
benchs.txt Normal file → Executable file
View File

BIN
disk.dsk Normal file → Executable file

Binary file not shown.

12
scripts/add-to-disk.sh Normal file → Executable file
View File

@ -1,19 +1,19 @@
#!/bin/bash
# Adds the gol.a2 Apple2 binary exceutable to the provided disk.dsk
# Adds the required files to the provided disk.dsk
# usage: add_to_disk PATH_TO_APPLECOMMANDER.jar
set -e
if (( $# != 1 )); then
if (( $# != 3 )); then
echo "Bad number of arguments"
echo "usage: add_to_disk.sh PATH_TO_APPLECOMMANDER.jar"
echo "usage: add_to_disk.sh PATH_TO_APPLECOMMANDER.jar PATH_TO_BINARY.a2 PATH_TO_DISK"
exit
fi
echo " . revoving previous instance of GOL form the disk"
java -jar ${1} -d disk.dsk GOL
java -jar ${1} -d ${3} GOL
echo " .. adding GOL to the disk"
java -jar ${1} -cc65 disk.dsk GOL BIN < gol.a2
java -jar ${1} -cc65 ${3} GOL BIN < ${2}
echo "DONE."

View File

@ -1,131 +0,0 @@
#! /usr/bin/env python3
import os.path
import argparse
from PIL import Image
# HiRes colors
BLACK = [0x00, 0x00, 0x00]
WHITE = [0xFF, 0xFF, 0xFF]
GREEN = [0x00, 0xFF, 0x00]
BLUE = [0x00, 0x00, 0xFF]
ORANGE = [0xFF, 0x77, 0x00]
VIOLET = [0xFF, 0x00, 0xFF]
Msg_Warning = ""
Color_Last = BLACK
def error(msg, err_code):
print(msg)
exit(err_code)
# Compute the Euclidean distance between 2 colors
def distance(color1, color2):
return (color1[0] - color2[0])**2 + (color1[1] - color2[1])**2 + (color1[2] - color2[2])**2
# Returns the nearest color
def nearest_color(color):
dist_black = distance(BLACK, color)
dist_white = distance(WHITE, color)
dist_green = distance(GREEN, color)
dist_blue = distance(BLUE, color)
dist_orange = distance(ORANGE, color)
dist_violet = distance(VIOLET, color)
dist_min = min([dist_black, dist_white, dist_green, dist_blue, dist_violet, dist_orange])
if dist_min == dist_black:
return BLACK
elif dist_min == dist_white:
return WHITE
elif dist_min == dist_green:
return GREEN
elif dist_min == dist_blue:
return BLUE
elif dist_min == dist_orange:
return ORANGE
else:
return VIOLET
# Returns True if the 7 pixel block can be converted into hires with no artifact
# Returns False otherwise
def compliant_hires(block):
global Msg_Warning
global Color_Last
# Test if colors from the two groups are in the block, aka "clashing"
group_one = False
group_two = False
nb_pixels = len(block)//3
for i in range(0, nb_pixels):
color = block[3*i:3*(i+1)]
if color == ORANGE or color == BLUE:
group_one = True
if color == GREEN or color == VIOLET:
group_two = True
if group_one and group_two:
Msg_Warning = "Colors from two groups, some clashing will occur!"
return False
# Test if there are two consecutive different colors in the group
Msg_Warning = "Two consecutive different colors may lead to an artifact"
color = block[0:3]
if Color_Last != BLACK and Color_Last != WHITE \
and color != BLACK and color != WHITE \
and color != Color_Last:
return False
for i in range(0, nb_pixels-1):
color = block[3*i:3*(i+1)]
if color != BLACK and color != WHITE:
color_next = block[3*(i+1):3*(i+2)]
if color_next != BLACK and color_next != WHITE \
and color != BLACK and color != WHITE \
and color != color_next:
return False
Color_Last = block[3*(nb_pixels-1):3*nb_pixels]
return True
# PARSING COMMAND LINE ARGUMENTS
parser = argparse.ArgumentParser(description="This script converts a 24bit RGB image file into an Apple II HiRes image.")
parser.add_argument("file", help="file to convert")
parser.add_argument("-o", "--output", help="output filename", required=False)
args = parser.parse_args()
# SANITIZE PARAMETERS
if not os.path.exists(args.file):
error("File " + args.file + " does not exist!", -1)
# MAIN
try:
# Open source image
image_rgb = Image.open(args.file).convert('RGB')
w = image_rgb.size[0]
h = image_rgb.size[1]
if w != 140 or h != 192:
error("Source image must be 140x192 pixels", -1)
# Quantize image to the HiRes's 6 colors
image_quantized = []
for y in range(0, h):
for x in range(0, w):
color = nearest_color(image_rgb.getpixel((x, y)))
for i in range(0, 3):
image_quantized.append(color[i])
if len(image_quantized) != 3*140*192:
error("Bad quantized size", -1)
# image_test = Image.frombytes('RGB', (140, 192), bytes(image_quantized))
# image_test.show()
# Test image conpliance to HiRes limitations
nb_pixels = 7 # nb pixels per line block
for i in range(0, 140 * 192 // nb_pixels):
block = image_quantized[3*i*nb_pixels:
3*(i+1)*nb_pixels]
if not compliant_hires(block):
print("Warning @block #" + str(i+1) + ": " + Msg_Warning)
except ValueError:
error(ValueError, -1)

0
src/file_io.c Normal file → Executable file
View File

0
src/file_io.h Normal file → Executable file
View File

49
src/game-of-life.cfg Executable file
View File

@ -0,0 +1,49 @@
# Default configuration (allowing for 3KB in LC)
FEATURES {
STARTADDRESS: default = $0803;
}
SYMBOLS {
__EXEHDR__: type = import;
__STACKSIZE__: type = weak, value = $0800; # 2k stack
__HIRESP2__: type = weak, value = $4000; # Start of HIRES PAGE2
__BSS__: type = weak, value = $6000; # Start of BSS after HIRES PAGE2
__HIMEM__: type = weak, value = $9600; # Presumed RAM end
__LCADDR__: type = weak, value = $D400; # Behind quit code
__LCSIZE__: type = weak, value = $0C00; # Rest of bank two
}
MEMORY {
ZP: file = "", define = yes, start = $0080, size = $001A;
HEADER: file = %O, start = %S - 4, size = $0004;
MAIN: file = %O, define = yes, start = %S, size = __HIRESP2__ - %S;
BSS: file = "", start = __BSS__, size = __HIMEM__ - __BSS__;
LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp;
EXEHDR: load = HEADER, type = ro;
STARTUP: load = MAIN, type = ro;
LOWCODE: load = MAIN, type = ro, optional = yes;
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw;
ONCE: load = MAIN, type = ro, define = yes;
LC: load = MAIN, run = LC, type = ro, optional = yes;
BSS: load = BSS, type = bss, define = yes;
}
FEATURES {
CONDES: type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__,
segment = ONCE;
CONDES: type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__,
segment = RODATA;
CONDES: type = interruptor,
label = __INTERRUPTOR_TABLE__,
count = __INTERRUPTOR_COUNT__,
segment = RODATA,
import = __CALLIRQ__;
}

0
src/gfx.asm Normal file → Executable file
View File

0
src/gfx.h Normal file → Executable file
View File

36
src/gol_apple2.c Normal file → Executable file
View File

@ -40,7 +40,7 @@ void editor( void ); /* lets the user draw some starting cell
int8_t editor_load_save( const uint8_t load_or_save );
void toggle_cell( const uint8_t x, const uint8_t y ); /* toggles the cell at the given coordinates. \
Returns the cursor X position */
void title_screen( void ); /* Loads and display the title screen */
void run( void ); /* runs the simulation */
void __fastcall__ update( void ); /* updates the simulation */
uint8_t __fastcall__ count_neighbours( uint8_t* cell ); /* counts nb neighbours of the cell */
@ -85,6 +85,7 @@ enum {
static uint8_t Cells[ NB_COLUMNS ][ NB_LINES ];
static uint8_t Cells_Future[ NB_COLUMNS ][ NB_LINES ];
static uint8_t Cells_Initial[ NB_COLUMNS ][ NB_LINES ];
//static uint8_t Title_Screen[ 0x2000 ];
/******************** CODE ************************/
@ -94,6 +95,9 @@ int main( int argc, char** argv )
(void)argc;
(void)argv;
/* Displaying the Title Screen */
title_screen();
init_asm( (uint8_t*)Cells, (uint8_t*)Cells_Future );
init_rnd_color();
@ -211,7 +215,7 @@ void editor( void )
uint8_t color_pixel;
uint8_t update_color = 1;
const char* const text = "J L I K: Move the cursor\nSPACE : Toggle a cell\n\n(L)oad - (S)ave - (D)one";
const char* const text = "H K U J: Move the cursor\nSPACE : Toggle a cell\n\n(L)oad - (S)ave - (D)one";
set_text( text );
//Place the cursor middle screen
@ -376,3 +380,31 @@ void run( void )
}
}
}
/****** HIRES SCREEN DEFINITIONS ***********/
#define HIRES_PAGE2 (char*)0x4000
#define HIRES_PAGE_SIZE 0x2000
#define SWITCH_GRAPHICS *((uint8_t*)0xC050)=1
#define SWITCH_FULLSCREEN *((uint8_t*)0xC052)=1
#define SWITCH_PAGE2 *((uint8_t*)0xC055)=1
#define SWITCH_HIRES *((uint8_t*)0xC057)=1
//The Title Screen asset is located in the "assets" folder
void title_screen( void )
{
uint8_t handle;
file_open("GOL.SCREEN", &handle);
if(file_read( handle, HIRES_PAGE2, HIRES_PAGE_SIZE ) != HIRES_PAGE_SIZE ) {
printf("\nERROR, CANNOT READ GOL.SCREEN\nERRNO: %x\n\n", file_error());
file_close(handle);
exit(-1);
}
file_close(handle);
SWITCH_GRAPHICS;
SWITCH_FULLSCREEN;
SWITCH_PAGE2;
SWITCH_HIRES;
cgetc();
}

0
src/gol_apple2_optimized.asm Normal file → Executable file
View File

0
src/gol_linux.c Normal file → Executable file
View File

7
src/mli.asm Normal file → Executable file
View File

@ -32,13 +32,6 @@ _call_to_mli:
JSR popa
STA Mli_Call
;+ DEBUG
; CMP #$CE
; BNE continue
;debug: JMP debug
;continue:
;- DEBUG
; Call MLI and return
JSR $BF00 ; MLI call entry point
Mli_Call:

0
src/rnd_colors.asm Normal file → Executable file
View File

0
src/rnd_colors.h Normal file → Executable file
View File