mirror of
https://github.com/Pixinn/gameoflife-appleii.git
synced 2024-06-08 00:29:37 +00:00
Color buffer initialized with random values
This commit is contained in:
parent
9687b85d0f
commit
3d08413c9c
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,4 +3,5 @@
|
|||
*.o
|
||||
*.map
|
||||
*.dsk
|
||||
*.bak
|
||||
gol
|
||||
|
|
4
Makefile
4
Makefile
|
@ -5,12 +5,12 @@ LINUX_OUT := gol.out
|
|||
|
||||
APPLE2_CL := $(CC65_HOME)/bin/cl65
|
||||
APPLE2_CC := $(CC65_HOME)/bin/cc65
|
||||
APPLE2_SRC := gol_apple2.c gol_apple2_optimized.asm gfx.asm
|
||||
APPLE2_SRC := gol_apple2.c gol_apple2_optimized.asm gfx.asm rnd_colors.asm
|
||||
APPLE2_MAP := gol_apple2.map
|
||||
APPLE2_CFLAGS := -Oirs -v -t apple2
|
||||
APPLE2_OUT := gol.a2
|
||||
|
||||
all: linux apple2
|
||||
all: apple2
|
||||
|
||||
linux: $(LINUX_SRC)
|
||||
$(LINUX_CC) -o $(LINUX_OUT) $? $(LINUX_CFLAGS)
|
||||
|
|
|
@ -3,3 +3,4 @@ Time to 50 iterations
|
|||
50ef808 : 111:94
|
||||
555db95 : 38:51
|
||||
d0f9aef : 15:43
|
||||
9687b85 : 27:27
|
||||
|
|
22
gfx.asm
22
gfx.asm
|
@ -107,11 +107,11 @@ _gfx_fill:
|
|||
;saving the context
|
||||
TAX
|
||||
LDA tmp1
|
||||
jsr pusha
|
||||
JSR pusha
|
||||
LDA ptr1
|
||||
jsr pusha
|
||||
JSR pusha
|
||||
LDA ptr2
|
||||
jsr pusha
|
||||
JSR pusha
|
||||
TXA
|
||||
;duplicate nybble color
|
||||
STA tmp1
|
||||
|
@ -163,11 +163,11 @@ fill_end:
|
|||
;displaying the page we filled
|
||||
; TODO SWITCH PAGES !!
|
||||
;restoring the context
|
||||
jsr popa
|
||||
JSR popa
|
||||
STA ptr2
|
||||
jsr popa
|
||||
JSR popa
|
||||
STA ptr1
|
||||
jsr popa
|
||||
JSR popa
|
||||
STA tmp1
|
||||
RTS
|
||||
|
||||
|
@ -179,15 +179,15 @@ _gfx_pixel:
|
|||
;saving the context
|
||||
TAX
|
||||
LDA tmp3
|
||||
jsr pusha
|
||||
JSR pusha
|
||||
LDA tmp2
|
||||
jsr pusha
|
||||
JSR pusha
|
||||
;LDA tmp1
|
||||
;jsr pusha
|
||||
;JSR pusha
|
||||
LDA ptr1
|
||||
jsr pusha
|
||||
JSR pusha
|
||||
LDA ptr2
|
||||
jsr pusha
|
||||
JSR pusha
|
||||
TXA
|
||||
|
||||
STA tmp3 ;coord_y
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <conio.h>
|
||||
|
||||
#include "gfx.h"
|
||||
#include "rnd_colors.h"
|
||||
|
||||
/******************* FUNCTION DEFINITIONS **************/
|
||||
|
||||
|
@ -65,7 +66,11 @@ int main( int argc, char** argv )
|
|||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
printf("PAUSE");
|
||||
cgetc();
|
||||
|
||||
init_asm( (uint8_t*)Cells, (uint8_t*)Cells_Future );
|
||||
init_rnd_color();
|
||||
|
||||
/* Running the state machine */
|
||||
while( State != STATE_QUIT )
|
||||
|
@ -118,6 +123,7 @@ void quit( void )
|
|||
void init_display( void )
|
||||
{
|
||||
register uint8_t i;
|
||||
clrscr();
|
||||
gfx_init( LOWRES, SPLIT );
|
||||
gfx_fill( BLACK );
|
||||
for( i = 0u; i < NB_COLUMNS; ++i ) {
|
||||
|
|
267
gol_apple2.c.bak
267
gol_apple2.c.bak
|
@ -1,267 +0,0 @@
|
|||
/* Standard headers */
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
/* Specific headers */
|
||||
#include <conio.h>
|
||||
|
||||
/******************* FUNCTION DEFINITIONS **************/
|
||||
|
||||
void init_display( void ); /* Inits displayed playfield */
|
||||
void draw_cells( void ); /* Draws the actual cells */
|
||||
void editor( void ); /* lets the user draw some starting cells */
|
||||
uint8_t toggle_cell( const uint8_t x, const uint8_t y ); /* toggles the cell at the given coordinates. \
|
||||
Returns the cursor X position */
|
||||
|
||||
void run( void ); /* runs the simulation */
|
||||
void __fastcall__ update( uint8_t* cells, uint8_t* cells_future ); /* updates the simulation */
|
||||
void __fastcall__ update_asm( uint8_t* cells, uint8_t* cells_future ); /* updates the simulation */
|
||||
uint8_t __fastcall__ count_neighbours( uint8_t* cell ); /* counts nb neighbours of the cell */
|
||||
|
||||
void quit( void );
|
||||
|
||||
/******************* CUSTOM TYPES AND VALUES DEFINITIONS ****************/
|
||||
|
||||
#define NB_LINES 23u
|
||||
#define NB_COLUMNS 40u
|
||||
|
||||
#define ALIVE 1u
|
||||
#define DEAD 0u
|
||||
#define SPRITE_ALIVE '0'
|
||||
#define SPRITE_DEAD ' '
|
||||
|
||||
#define STATE_INIT 0u
|
||||
#define STATE_EDITOR 1u
|
||||
#define STATE_RUN 2u
|
||||
#define STATE_QUIT 3u
|
||||
uint8_t State = STATE_INIT;
|
||||
|
||||
#define NO_KEY '\0'
|
||||
char KeyPressed = NO_KEY;
|
||||
|
||||
|
||||
/******************* STATIC GLOBAL VARIABLES ******************/
|
||||
|
||||
uint8_t Cells[ NB_COLUMNS ][ NB_LINES ];
|
||||
uint8_t Cells_Future[ NB_COLUMNS ][ NB_LINES ];
|
||||
uint8_t Cells_Initial[ NB_COLUMNS ][ NB_LINES ];
|
||||
|
||||
/******************** CODE ************************/
|
||||
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
/* Running the state machine */
|
||||
while( State != STATE_QUIT )
|
||||
{
|
||||
switch (State) {
|
||||
case STATE_INIT:
|
||||
memset( Cells, DEAD, sizeof(Cells) );
|
||||
init_display();
|
||||
State = STATE_EDITOR;
|
||||
break;
|
||||
case STATE_EDITOR:
|
||||
editor();
|
||||
State = STATE_RUN;
|
||||
break;
|
||||
case STATE_RUN:
|
||||
run();
|
||||
if( KeyPressed == 'e' ) { /* Go back to editor */
|
||||
State = STATE_EDITOR;
|
||||
} else if( KeyPressed == 'r' ) { /* reset and rerun */
|
||||
memcpy( Cells, Cells_Initial, sizeof(Cells) );
|
||||
memcpy( Cells_Future, Cells_Initial, sizeof(Cells_Future) );
|
||||
draw_cells();
|
||||
} else if( KeyPressed == 'q' ) { /* quit */
|
||||
State = STATE_QUIT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("ERROR!");
|
||||
State = STATE_QUIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
quit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void quit( void )
|
||||
{
|
||||
uint8_t x, y;
|
||||
screensize (&x, &y);
|
||||
gotoxy( 1u, y-1u );
|
||||
printf("BYE BYE!");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
void init_display( void )
|
||||
{
|
||||
clrscr();
|
||||
chlinexy (1u, 0u, NB_COLUMNS-2u );
|
||||
chlinexy (1u, NB_LINES-1u, NB_COLUMNS-2u );
|
||||
cvlinexy (0u, 1u, NB_LINES-1u );
|
||||
cvlinexy (NB_COLUMNS-1u, 1u, NB_LINES-1u );
|
||||
cputcxy ( 0u, 0u, '+' );
|
||||
cputcxy ( 0u , NB_LINES-1u,'+');
|
||||
cputcxy ( NB_COLUMNS-1u, 0u,'+');
|
||||
cputcxy ( NB_COLUMNS-1u, NB_LINES-1u,'+');
|
||||
}
|
||||
|
||||
|
||||
void draw_cells( void ) {
|
||||
uint8_t x, y;
|
||||
for( x = 1u; x < NB_COLUMNS - 1u; ++x )
|
||||
{
|
||||
for( y = 1u; y < NB_LINES - 1u; ++y )
|
||||
{
|
||||
if( Cells[x][y] == ALIVE ) {
|
||||
cputcxy ( x, y, SPRITE_ALIVE );
|
||||
} else {
|
||||
cputcxy ( x, y, SPRITE_DEAD );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void editor( void )
|
||||
{
|
||||
#define KEY_LEFT 'j'
|
||||
#define KEY_DOWN 'k'
|
||||
#define KEY_UP 'i'
|
||||
#define KEY_RIGHT 'l'
|
||||
|
||||
uint8_t quit, x, y;
|
||||
|
||||
gotoxy( 0u, NB_LINES );
|
||||
printf("EDITOR (D)one");
|
||||
|
||||
x = NB_COLUMNS >> 1u;
|
||||
y = NB_LINES >> 1u;
|
||||
gotoxy(x,y);
|
||||
|
||||
quit = 0;
|
||||
while ( quit == 0)
|
||||
{
|
||||
cursor(1);
|
||||
KeyPressed = cgetc();
|
||||
switch (KeyPressed) {
|
||||
case KEY_LEFT:
|
||||
if( x > 1u ) { gotoxy( --x, y ); }
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
if( y < NB_LINES-2u ) { gotoxy( x, ++y ); }
|
||||
break;
|
||||
case KEY_UP:
|
||||
if( y > 1u ) { gotoxy( x, --y ); }
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
if( x < NB_COLUMNS-2u ) { gotoxy( ++x, y ); }
|
||||
break;
|
||||
case ' ':
|
||||
x = toggle_cell( x, y );
|
||||
break;
|
||||
case 'd':
|
||||
quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cells was updated by the calls to toggle() */
|
||||
memcpy( Cells_Future, Cells, sizeof(Cells_Future) );
|
||||
memcpy( Cells_Initial, Cells, sizeof(Cells_Initial) );
|
||||
}
|
||||
|
||||
|
||||
uint8_t toggle_cell( const uint8_t x, const uint8_t y )
|
||||
{
|
||||
char* cell;
|
||||
if( x == 0u || x >= NB_COLUMNS-1u || y == 0u || y >= NB_LINES-1u ) { return x; }
|
||||
cell = &Cells[x][y];
|
||||
if( *cell == DEAD ) {
|
||||
*cell = ALIVE;
|
||||
cputc( SPRITE_ALIVE );
|
||||
} else {
|
||||
*cell = DEAD;
|
||||
cputc( SPRITE_DEAD );
|
||||
}
|
||||
return wherex ();
|
||||
}
|
||||
|
||||
|
||||
void run( void )
|
||||
{
|
||||
char str_nb_iteration [5];
|
||||
uint16_t nb_iterations = 2u;
|
||||
KeyPressed = NO_KEY;
|
||||
cursor(0);
|
||||
|
||||
//+ DEBUG
|
||||
gotoxy(0,0);
|
||||
printf("Cells:0x%x - Cells_future:0x%x",(uint16_t)(&Cells[0][0]),(uint16_t)(&Cells_Future[0][0]));
|
||||
cgetc();
|
||||
//- DEBUG
|
||||
|
||||
|
||||
gotoxy( 0u, NB_LINES );
|
||||
printf("Iteration:1 (R)eset (E)ditor (Q)uit");
|
||||
while( KeyPressed == NO_KEY)
|
||||
{
|
||||
/* Evolving the cells */
|
||||
update_asm( &Cells[0][0], &Cells_Future[0][0] );
|
||||
/* Printing iterations */
|
||||
gotoxy(10u, NB_LINES);
|
||||
printf( itoa(nb_iterations++, str_nb_iteration, 10) );
|
||||
/* Testing key pressed */
|
||||
if( kbhit() ){
|
||||
KeyPressed = cgetc();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void __fastcall__ update( uint8_t* cells, uint8_t* cells_future )
|
||||
{
|
||||
uint8_t x, y;
|
||||
uint8_t* cell_neighbourhoud = cells; // cell_neighbourhoud = &Cells[0][0];
|
||||
uint8_t* cell = cell_neighbourhoud + NB_LINES + 1u; // cell = &Cells[1][1];
|
||||
uint8_t* cell_future = cells_future + NB_LINES + 1u; // cell_future = &Cells_Future[1][1];
|
||||
for( y = 1u; y < NB_LINES - 1u; ++y )
|
||||
{
|
||||
|
||||
uint8_t* cell_line = cell;
|
||||
uint8_t* cell_neighbourhoud_line = cell_neighbourhoud;
|
||||
uint8_t* cell_future_line = cell_future;
|
||||
for( x = 1u; x < NB_COLUMNS - 1u; ++x)
|
||||
{
|
||||
uint8_t nb_neighbours = count_neighbours( cell_neighbourhoud_line );
|
||||
if( *cell_line == ALIVE && \
|
||||
(nb_neighbours < 2u || nb_neighbours > 3u )
|
||||
) {
|
||||
*cell_future_line = DEAD;
|
||||
cputcxy( x, y, SPRITE_DEAD );
|
||||
}
|
||||
else if( *cell_line == DEAD && nb_neighbours == 3u ) {
|
||||
*cell_future_line = ALIVE;
|
||||
cputcxy( x, y, SPRITE_ALIVE );
|
||||
}
|
||||
cell_line += NB_LINES;
|
||||
cell_neighbourhoud_line += NB_LINES;
|
||||
cell_future_line += NB_LINES;
|
||||
}
|
||||
++cell;
|
||||
++cell_neighbourhoud;
|
||||
++cell_future;
|
||||
}
|
||||
memcpy( cells, cells_future, sizeof(Cells) );
|
||||
}
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
|
||||
.include "apple2.inc"
|
||||
.include "zeropage.inc"
|
||||
|
||||
|
||||
.export _count_neighbours
|
||||
.export _update_asm
|
||||
|
||||
.import _Cells
|
||||
.import _Cells_Future
|
||||
|
||||
|
||||
.define NB_LINES 23
|
||||
.define NB_COLUMNS 40
|
||||
.define JUMP_BEGINNING_NEXT_LINE NB_LINES - 2
|
||||
|
||||
|
||||
|
||||
|
||||
; ******************
|
||||
;void __fastcall__ update( uint8_t* cells, uint8_t* cells_future )
|
||||
;cells_future in sreg
|
||||
;cells in ptr1
|
||||
;cells in neighbourhoud in ptr2
|
||||
;current cell in ptr3
|
||||
;future cell in ptr4
|
||||
_update_asm:
|
||||
|
||||
;preambule
|
||||
STA ptr1
|
||||
STX ptr1+1
|
||||
STA ptr2
|
||||
STX ptr2+1
|
||||
|
||||
RTS
|
||||
|
||||
|
||||
; ******************
|
||||
;uint8_t __fastcall__ count_neighbours( uint8_t* cell )
|
||||
;param: cell is in AX
|
||||
_count_neighbours:
|
||||
|
||||
;ASSUMPTIONS:
|
||||
; -> A and Y (offset to starting ptr) won't overflow!
|
||||
|
||||
;init
|
||||
STA ptr1
|
||||
STX ptr1+1
|
||||
LDA #0
|
||||
LDY #0
|
||||
CLC
|
||||
|
||||
;acc 1st row
|
||||
ADC (ptr1),Y
|
||||
INY
|
||||
ADC (ptr1),Y
|
||||
INY
|
||||
ADC (ptr1),Y
|
||||
|
||||
;next row
|
||||
STA tmp1
|
||||
TYA
|
||||
ADC #JUMP_BEGINNING_NEXT_LINE
|
||||
TAY
|
||||
LDA tmp1
|
||||
ADC (ptr1),Y
|
||||
INY
|
||||
INY
|
||||
ADC (ptr1),Y
|
||||
|
||||
;next row
|
||||
STA tmp1
|
||||
TYA
|
||||
ADC #JUMP_BEGINNING_NEXT_LINE
|
||||
TAY
|
||||
LDA tmp1
|
||||
ADC (ptr1),Y
|
||||
INY
|
||||
ADC (ptr1),Y
|
||||
INY
|
||||
ADC (ptr1),Y
|
||||
|
||||
;return
|
||||
TAX
|
||||
LDX #0
|
||||
RTS
|
||||
|
55
rnd_colors.asm
Executable file
55
rnd_colors.asm
Executable file
|
@ -0,0 +1,55 @@
|
|||
|
||||
.include "apple2.inc"
|
||||
.include "zeropage.inc"
|
||||
|
||||
.import pusha
|
||||
.import popa
|
||||
|
||||
.export _init_rnd_color
|
||||
|
||||
|
||||
.BSS
|
||||
Colors: .dword $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0
|
||||
.dword $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0
|
||||
.dword $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0
|
||||
.dword $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0
|
||||
|
||||
|
||||
.CODE
|
||||
|
||||
; void __fastcall__ init_rnd_color( void )
|
||||
; Fills Colors with 8bits random values
|
||||
; Code inspired by: http://www.codebase64.org/doku.php?id=base:small_fast_8-bit_prng
|
||||
_init_rnd_color:
|
||||
seed := tmp1
|
||||
LDA tmp1
|
||||
JSR pusha
|
||||
|
||||
LDA #123
|
||||
STA seed
|
||||
LDX #0
|
||||
loop: ; for X = 0 to 255
|
||||
LDA seed
|
||||
BEQ doEor
|
||||
ASL
|
||||
BEQ noEor ;if the input was $80, skip the EOR
|
||||
BCC noEor
|
||||
doEor:
|
||||
EOR #$2B
|
||||
noEor:
|
||||
STA seed
|
||||
AND #$0F ; color is in lo-nybble
|
||||
BEQ loop ; 0 (BLACK) not accepted
|
||||
CMP #$0F
|
||||
BEQ loop ; 0xF (WHITE) not accepted
|
||||
STA Colors,X
|
||||
INX ; next X
|
||||
CPX #0
|
||||
BEQ loop_end
|
||||
CLC
|
||||
BCC loop
|
||||
loop_end:
|
||||
|
||||
JSR popa
|
||||
STA tmp1
|
||||
RTS
|
6
rnd_colors.h
Executable file
6
rnd_colors.h
Executable file
|
@ -0,0 +1,6 @@
|
|||
#ifndef __RND_COLOTS__H_
|
||||
#define __RND_COLOTS__H_
|
||||
|
||||
void init_rnd_color( void ); /* Inits a buffer of 256 random colors */
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user