cvu_set_sprite4() no more inline b/c sdcc barfs

This commit is contained in:
Steven Hugg 2019-08-18 07:01:57 -04:00
parent 151bc19e23
commit a216997bd6
11 changed files with 1428 additions and 21 deletions

View File

@ -1,4 +1,4 @@

#include <stdlib.h>
#include <string.h>
#include <cv.h>
@ -6,10 +6,7 @@
#include "common.h"
//#link "common.c"
#ifdef CV_SMS
//#link "fonts.s"
#endif
#define XOFS 12 // sprite horiz. offset
@ -592,14 +589,18 @@ void play_scene() {
}
void setup_graphics() {
#ifndef CV_MSX
cvu_memtovmemcpy(PATTERN, (void *)(font_bitmap_0 - '0'*8), 0x800);
#endif
cvu_memtovmemcpy(PATTERN+8*64, char_table, sizeof(char_table));
cvu_memtovmemcpy(PATTERN+8*128, static_sprite_table, sizeof(static_sprite_table));
#ifndef CV_MSX
cvu_vmemset(COLOR, 0x30|BGCOL, 8); // set color for chars 0-63
cvu_vmemset(COLOR+8, 0x0|BGCOL, 32-8); // set chars 63-255
cvu_vmemset(COLOR+16, 0xb0|BGCOL, 1); // set chars 128-128+8
#endif
cvu_memtovmemcpy(SPRITE_PATTERNS, sprite_table, sizeof(sprite_table));
flip_sprite_patterns(SPRITE_PATTERNS + 512, (const byte*)sprite_table, sizeof(sprite_table));
flip_sprite_patterns(SPRITE_PATTERNS + 384, (const byte*)blimp_sprite_table, sizeof(blimp_sprite_table));

367
presets/msx/eliza.c Normal file
View File

@ -0,0 +1,367 @@
/* eliza.c
* ys
* original code by Weizenbaum, 1966
* this rendition based on Charles Hayden's Java implementation from http://chayden.net/eliza/Eliza.html
*
* Note: There are certainly far more optimal and elegant ways to code this... we kept this
* structure to be faithful to the original. -scaz
*/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#define NUMKEYWORDS 37
#define MAXLINELEN 40
#define NUMSWAPS 14
#include "msxbios.h"
//#link "msxbios.c"
const char *keywords[]= {
"CAN YOU","CAN I","YOU ARE","YOURE","I DONT","I FEEL",
"WHY DONT YOU","WHY CANT I","ARE YOU","I CANT","I AM","IM ",
"YOU ","I WANT","WHAT","HOW","WHO","WHERE",
"WHEN","WHY",
"NAME","CAUSE","SORRY","DREAM","HELLO","HI ","MAYBE",
" NO","YOUR","ALWAYS","THINK","ALIKE","YES","FRIEND",
"COMPUTER","CAR","NOKEYFOUND"};
const char *SWAPS[NUMSWAPS][2] = {
{"ARE","AM"},
{"WERE", "WAS"},
{"YOU","I"},
{"YOUR", "MY"},
{"IVE", "YOU'VE"},
{"IM", "YOU'RE"},
{"YOU", "ME"},
{"ME", "YOU"},
{"AM","ARE"},
{"WAS", "WERE"},
{"I","YOU"},
{"MY", "YOUR"},
{"YOUVE", "I'VE"},
{"YOURE", "I'M"}
};
int ResponsesPerKeyword[NUMKEYWORDS]= {
3,2,4,4,4,3,
3,2,3,3,4,4,
3,5,9,9,9,9,
9,9,
2,4,4,4,1,1,5,
5,2,4,3,7,3,6,
7,5,6};
const char *responses[NUMKEYWORDS][9] = {
{ "DON'T YOU BELIEVE THAT I CAN*",
"PERHAPS YOU WOULD LIKE TO BE ABLE TO*",
"YOU WANT ME TO BE ABLE TO*"},
{ "PERHAPS YOU DON'T WANT TO*",
"DO YOU WANT TO BE ABLE TO*"},
{ "WHAT MAKES YOU THINK I AM*",
"DOES IT PLEASE YOU TO BELIEVE I AM*",
"PERHAPS YOU WOULD LIKE TO BE*",
"DO YOU SOMETIMES WISH YOU WERE*"},
{ "WHAT MAKES YOU THINK I AM*",
"DOES IT PLEASE YOU TO BELIEVE I AM*",
"PERHAPS YOU WOULD LIKE TO BE*",
"DO YOU SOMETIMES WISH YOU WERE*"},
{ "DON'T YOU REALLY*",
"WHY DON'T YOU*",
"DO YOU WISH TO BE ABLE TO*",
"DOES THAT TROUBLE YOU?"},
{ "TELL ME MORE ABOUT SUCH FEELINGS.",
"DO YOU OFTEN FEEL*",
"DO YOU ENJOY FEELING*"},
{ "DO YOU REALLY BELIEVE I DON'T*",
"PERHAPS IN GOOD TIME I WILL*",
"DO YOU WANT ME TO*"},
{ "DO YOU THINK YOU SHOULD BE ABLE TO*",
"WHY CAN'T YOU*"},
{ "WHY ARE YOU INTERESTED IN WHETHER OR NOT I AM*",
"WOULD YOU PREFER IF I WERE NOT*",
"PERHAPS IN YOUR FANTASIES I AM*"},
{ "HOW DO YOU KNOW YOU CAN'T*",
"HAVE YOU TRIED?",
"PERHAPS YOU CAN NOW*"},
{ "DID YOU COME TO ME BECAUSE YOU ARE*",
"HOW LONG HAVE YOU BEEN*",
"DO YOU BELIEVE IT IS NORMAL TO BE*",
"DO YOU ENJOY BEING*"},
{ "DID YOU COME TO ME BECAUSE YOU ARE*",
"HOW LONG HAVE YOU BEEN*",
"DO YOU BELIEVE IT IS NORMAL TO BE*",
"DO YOU ENJOY BEING*"},
{ "WE WERE DISCUSSING YOU-- NOT ME.",
"OH, I*",
"YOU'RE NOT REALLY TALKING ABOUT ME, ARE YOU?"},
{ "WHAT WOULD IT MEAN TO YOU IF YOU GOT*",
"WHY DO YOU WANT*",
"SUPPOSE YOU SOON GOT*",
"WHAT IF YOU NEVER GOT*",
"I SOMETIMES ALSO WANT*"},
{ "WHY DO YOU ASK?",
"DOES THAT QUESTION INTEREST YOU?",
"WHAT ANSWER WOULD PLEASE YOU THE MOST?",
"WHAT DO YOU THINK?",
"ARE SUCH QUESTIONS ON YOUR MIND OFTEN?",
"WHAT IS IT THAT YOU REALLY WANT TO KNOW?",
"HAVE YOU ASKED ANYONE ELSE?",
"HAVE YOU ASKED SUCH QUESTIONS BEFORE?",
"WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?"},
{ "WHY DO YOU ASK?",
"DOES THAT QUESTION INTEREST YOU?",
"WHAT ANSWER WOULD PLEASE YOU THE MOST?",
"WHAT DO YOU THINK?",
"ARE SUCH QUESTIONS ON YOUR MIND OFTEN?",
"WHAT IS IT THAT YOU REALLY WANT TO KNOW?",
"HAVE YOU ASKED ANYONE ELSE?",
"HAVE YOU ASKED SUCH QUESTIONS BEFORE?",
"WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?"},
{ "WHY DO YOU ASK?",
"DOES THAT QUESTION INTEREST YOU?",
"WHAT ANSWER WOULD PLEASE YOU THE MOST?",
"WHAT DO YOU THINK?",
"ARE SUCH QUESTIONS ON YOUR MIND OFTEN?",
"WHAT IS IT THAT YOU REALLY WANT TO KNOW?",
"HAVE YOU ASKED ANYONE ELSE?",
"HAVE YOU ASKED SUCH QUESTIONS BEFORE?",
"WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?"},
{ "WHY DO YOU ASK?",
"DOES THAT QUESTION INTEREST YOU?",
"WHAT ANSWER WOULD PLEASE YOU THE MOST?",
"WHAT DO YOU THINK?",
"ARE SUCH QUESTIONS ON YOUR MIND OFTEN?",
"WHAT IS IT THAT YOU REALLY WANT TO KNOW?",
"HAVE YOU ASKED ANYONE ELSE?",
"HAVE YOU ASKED SUCH QUESTIONS BEFORE?",
"WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?"},
{ "WHY DO YOU ASK?",
"DOES THAT QUESTION INTEREST YOU?",
"WHAT ANSWER WOULD PLEASE YOU THE MOST?",
"WHAT DO YOU THINK?",
"ARE SUCH QUESTIONS ON YOUR MIND OFTEN?",
"WHAT IS IT THAT YOU REALLY WANT TO KNOW?",
"HAVE YOU ASKED ANYONE ELSE?",
"HAVE YOU ASKED SUCH QUESTIONS BEFORE?",
"WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?"},
{ "WHY DO YOU ASK?",
"DOES THAT QUESTION INTEREST YOU?",
"WHAT ANSWER WOULD PLEASE YOU THE MOST?",
"WHAT DO YOU THINK?",
"ARE SUCH QUESTIONS ON YOUR MIND OFTEN?",
"WHAT IS IT THAT YOU REALLY WANT TO KNOW?",
"HAVE YOU ASKED ANYONE ELSE?",
"HAVE YOU ASKED SUCH QUESTIONS BEFORE?",
"WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?"},
{ "NAMES DON'T INTEREST ME.",
"I DON'T CARE ABOUT NAMES-- PLEASE GO ON."},
{ "IS THAT THE REAL REASON?",
"DON'T ANY OTHER REASONS COME TO MIND?",
"DOES THAT REASON EXPLAIN ANY THING ELSE?",
"WHAT OTHER REASONS MIGHT THERE BE?"},
{ "PLEASE DON'T APOLOGIZE.",
"APOLOGIES ARE NOT NECESSARY.",
"WHAT FEELINGS DO YOU HAVE WHEN YOU APOLOGIZE?",
"DON'T BE SO DEFENSIVE!"},
{ "WHAT DOES THAT DREAM SUGGEST TO YOU?",
"DO YOU DREAM OFTEN?",
"WHAT PERSONS APPEAR IN YOUR DREAMS?",
"ARE YOU DISTURBED BY YOUR DREAMS?"},
{ "HOW DO YOU DO--PLEASE STATE YOUR PROBLEM."},
{ "HOW DO YOU DO--PLEASE STATE YOUR PROBLEM."},
{ "YOU DON'T SEEM QUITE CERTAIN.",
"WHY THE UNCERTAIN TONE?",
"CAN'T YOU BE MORE POSITIVE?",
"YOU AREN'T SURE?",
"DON'T YOU KNOW?"},
{ "ARE YOU SAYING NO JUST TO BE NEGATIVE?",
"YOU ARE BEING A BIT NEGATIVE.",
"WHY NOT?",
"ARE YOU SURE?",
"WHY NO?"},
{ "WHY ARE YOU CONCERNED ABOUT MY*",
"WHAT ABOUT YOUR OWN*"},
{ "CAN YOU THINK OF A SPECIFIC EXAMPLE?",
"WHEN?",
"WHAT ARE YOU THINKING OF?",
"REALLY, ALWAYS?"},
{ "DO YOU REALLY THINK SO?",
"BUT YOU ARE NOT SURE YOU*",
"DO YOU DOUBT YOU*"},
{ "IN WHAT WAY?",
"WHAT RESEMBLANCE DO YOU SEE?",
"WHAT DOES THE SIMILARITY SUGGEST TO YOU?",
"WHAT OTHER CONNECTIONS DO YOU SEE?",
"COULD THERE REALLY BE SOME CONNECTION?",
"HOW?"},
{ "YOU SEEM QUITE POSITIVE.",
"ARE YOU SURE?",
"I SEE.",
"I UNDERSTAND."},
{ "WHY DO YOU BRING UP THE TOPIC OF FRIENDS?",
"DO YOUR FRIENDS WORRY YOU?",
"DO YOUR FRIENDS PICK ON YOU?",
"ARE YOU SURE YOU HAVE ANY FRIENDS?",
"DO YOU IMPOSE ON YOUR FRIENDS?",
"PERHAPS YOUR LOVE FOR FRIENDS WORRIES YOU?"},
{ "DO COMPUTERS WORRY YOU?",
"ARE YOU TALKING ABOUT ME IN PARTICULAR?",
"ARE YOU FRIGHTENED BY MACHINES?",
"WHY DO YOU MENTION COMPUTERS?",
"WHAT DO YOU THINK MACHINES HAVE TO DO WITH YOUR PROBLEM?",
"DON'T YOU THINK COMPUTERS CAN HELP PEOPLE?",
"WHAT IS IT ABOUT MACHINES THAT WORRIES YOU?"},
{ "OH, DO YOU LIKE CARS?",
"MY FAVORITE CAR IS A LAMBORGINI COUNTACH. WHAT IS YOUR FAVORITE CAR?",
"MY FAVORITE CAR COMPANY IS FERRARI. WHAT IS YOURS?",
"DO YOU LIKE PORSCHES?",
"DO YOU LIKE PORSCHE TURBO CARRERAS?"},
{ "SAY, DO YOU HAVE ANY PSYCHOLOGICAL PROBLEMS?",
"WHAT DOES THAT SUGGEST TO YOU?",
"I SEE.",
"I'M NOT SURE I UNDERSTAND YOU FULLY.",
"COME, COME ELUCIDATE YOUR THOUGHTS.",
"CAN YOU ELABORATE ON THAT?",
"THAT IS QUITE INTERESTING."}
};
void print_center(const char *msg) {
int numspaces=(MAXLINELEN-strlen(msg))/2;
int i;
for(i=0;i<numspaces;i++)
printf(" ");
printf("%s\n", msg);
return;
}
void print_title () {
printf("\n\n");
print_center("*** ELIZA ***");
print_center("Original code by Weizenbaum, 1966");
print_center("To stop Eliza, type 'bye'");
printf("\n\n");
printf("HI! I'M ELIZA. WHAT'S YOUR PROBLEM?\n");
}
void readline(char *instr) {
char c;
int slen=0;
c=getchar();
while (c != '\n')
{
// removes punctuation and sets to uppercase
if(isalpha(c) || isspace(c))
instr[slen++]=toupper(c);
if(slen>MAXLINELEN-1)
{
printf("Exceeded Max Line Length\n");
}
c=getchar();
}
instr[slen]='\0';
}
void main()
{
int k,baseLength;
int whichReply[NUMKEYWORDS];
char lastinput[MAXLINELEN];
char reply[MAXLINELEN];
char *baseResponse, *token;
const char separator[2]=" ";
char inputstr[MAXLINELEN];
int x,s;
char *location;
// use the first reply for each keyword match the first time you see that keyword
for (x=0;x<NUMKEYWORDS; x++) {
whichReply[x] = 0;
}
// print a nice centered title screen
INITXT();
SCNCNT = 1; // set keyboard scan counter
print_title();
lastinput[0]='\0';
while (1) {
printf(">");
readline(inputstr);
printf("\n");
// check for termination
if (strcmp(inputstr,"BYE")==0)
break;
// check for repeated entries
if (strcmp(lastinput,inputstr)==0)
{
printf("PLEASE DON'T REPEAT YOURSELF!\n");
continue;
}
strncpy(lastinput,inputstr,strlen(inputstr)+1);
// see if any of the keywords is contained in the input
// if not, we use the last element of keywords as our default responses
strcpy(reply,"");
for(k=0;k<NUMKEYWORDS-1;k++)
{
location=strstr(inputstr, keywords[k]);
if(location != NULL)
break;
}
// Build Eliza's response
// start with Eliza's canned response, based on the keyword match
baseResponse = (char *) responses[k][whichReply[k]];
baseLength = strlen(baseResponse);
if(baseResponse[baseLength-1] != '*')
{
// if we have a baseResponse without an asterix, just use it as-is
strcat(reply, baseResponse);
}
else
{
// if we do have an asterix, fill in the remaining with the user input
// use all but the last character of the base response
strncat(reply, baseResponse, baseLength-1);
// now add in the rest of the user's input, starting at <location>
// but skip over the keyword itself
location+=strlen(keywords[k]);
// take them one word at a time, so that we can substitute pronouns
token = strtok(location, separator);
while(token != NULL)
{
for(s=0;s<NUMSWAPS;s++)
{
if(strcmp(SWAPS[s][0], token) == 0)
{
token = (char *) SWAPS[s][1];
break;
}
}
strcat(reply," ");
strcat(reply, token);
token=strtok(NULL, separator);
};
strcat(reply, "?");
}
printf("%s\n", reply);
// next time, use the next appropriate reply for that keyword
whichReply[k]++;
if ( whichReply[k] >= ResponsesPerKeyword[k])
whichReply[k] = 0;
}
printf( "GOODBYE! THANKS FOR VISITING WITH ME...\n");
}

View File

@ -1,9 +1,24 @@
/*
http://map.grauw.nl/resources/msxbios.php
http://map.grauw.nl/resources/msxsystemvars.php
https://www.msx.org/wiki/System_variables_and_work_area
*/
#include "msxbios.h"
#define MSXUSR_LOAD_A() __asm__("ld a,l");
#define MSXUSR_LOAD_E() __asm__("ld e,h");
#define MSXUSR_RTN_A() __asm__("ld l,a");
#define MSXUSR_RTN_Z()\
__asm__("ld l,#0");\
__asm__("ret nz");\
__asm__("inc l");
#define MSXUSR_RTN_C()\
__asm__("ld l,#0");\
__asm__("ret nc");\
__asm__("inc l");
union {
struct {
@ -29,14 +44,14 @@ void LOAD_REGS() {
void RDSLT(uint8_t slot, uint16_t addr) {
REGS.b.a = slot;
REGS.w.hl = addr;
MSXUSR(0x000c);
MSXUSR_LOAD_REGS(0x000c);
}
void WRSLT(uint8_t slot, uint16_t addr, uint8_t value) {
REGS.b.a = slot;
REGS.w.hl = addr;
REGS.b.e = value;
MSXUSR(0x0014);
MSXUSR_LOAD_REGS(0x0014);
}
void DISSCR() __z88dk_fastcall {
@ -54,9 +69,9 @@ void WRTVDP(uint16_t reg_data) __z88dk_fastcall {
MSXUSR(0x0047);
}
void RDVRM(uint16_t addr) __z88dk_fastcall {
uint8_t RDVRM(uint16_t addr) __z88dk_fastcall {
addr;
MSXUSR(0x0047);
MSXUSR(0x004a);
MSXUSR_RTN_A();
}
@ -160,9 +175,7 @@ uint16_t WRTPSG(uint16_t reg_data) __z88dk_fastcall {
uint8_t CHSNS() __z88dk_fastcall {
MSXUSR(0x009c);
__asm__("ld hl,#0");
__asm__("ret z");
__asm__("inc hl");
MSXUSR_RTN_Z();
}
char CHGET() __z88dk_fastcall {
@ -228,6 +241,7 @@ uint8_t GTPDL(uint8_t index) __z88dk_fastcall {
MSXUSR_RTN_A();
}
/*
void RIGHTC() __z88dk_fastcall {
MSXUSR(0x00fc);
}
@ -240,11 +254,62 @@ void UPC() __z88dk_fastcall {
MSXUSR(0x0102);
}
uint8_t TUPC() __z88dk_fastcall {
MSXUSR(0x0105);
MSXUSR_RTN_C();
}
void DOWNC() __z88dk_fastcall {
MSXUSR(0x0108);
}
void RDVDP() __z88dk_fastcall {
uint8_t TDOWNC() __z88dk_fastcall {
MSXUSR(0x010b);
MSXUSR_RTN_C();
}
void SCALXY() __z88dk_fastcall {
MSXUSR(0x010e);
}
*/
void MAPXY() __z88dk_fastcall {
MSXUSR(0x0111);
}
uint16_t FETCHC_ADDR() __z88dk_fastcall {
MSXUSR(0x0114);
}
/*
void STOREC(uint16_t addr, uint8_t mask) {
REGS.w.hl = addr;
REGS.b.a = mask;
MSXUSR_LOAD_REGS(0x0117);
}
void SETATR(uint8_t attr) __z88dk_fastcall {
attr;
MSXUSR_LOAD_A();
MSXUSR(0x011a);
}
uint8_t READC() __z88dk_fastcall {
MSXUSR(0x011d);
MSXUSR_RTN_A();
}
void SETC() __z88dk_fastcall {
MSXUSR(0x0120);
}
void NSETCX(uint16_t fillcount) __z88dk_fastcall {
fillcount;
MSXUSR(0x0123);
}
*/
uint8_t RDVDP() __z88dk_fastcall {
MSXUSR(0x013e);
MSXUSR_RTN_A();
}
@ -263,5 +328,12 @@ void KILBUF() __z88dk_fastcall {
// for stdio.h
int putchar(int ch) {
CHPUT(ch);
if (ch == '\n') CHPUT('\r'); // convert CR to CRLF
return ch;
}
char getchar() {
char ch = CHGET();
putchar(ch); // echo
if (ch == '\r') ch = '\n';
return ch;
}

View File

@ -62,6 +62,21 @@ uint8_t __at(0xf3ea) BAKCLR;
// F3EB: code for the standard border color (ini:7)
uint8_t __at(0xf3eb) BDRCLR;
//Pixel lcocation
uint16_t __at(0xf92a) CLOC;
//Pixel mask
uint8_t __at(0xf92c) CMASK;
//Attribute byte for SETC
uint8_t __at(0xf3f2) ATRBYT;
//Key scan timing
uint8_t __at(0xf3f6) SCNCNT;
//Key repeat timer
uint8_t __at(0xf3f7) REPCNT;
//Address in the keyboard buffer where a character will be written
uint8_t* __at(0xf3f8) PUTPNT;
//Address in the keyboard buffer where the next character is read
uint8_t* __at(0xf3fa) GETPNT;
/// FUNCTIONS
// Reads the value of an address in another slot
@ -75,7 +90,7 @@ void ENASCR() __z88dk_fastcall;
// write data in the VDP-register
void WRTVDP(uint16_t reg_data) __z88dk_fastcall;
// Reads the content of VRAM
void RDVRM(uint16_t addr) __z88dk_fastcall;
uint8_t RDVRM(uint16_t addr) __z88dk_fastcall;
// Writes data in VRAM
void WRTVRM(uint16_t addr, uint8_t data);
// Enable VDP to read
@ -139,11 +154,25 @@ uint8_t GTPAD(uint8_t index) __z88dk_fastcall;
// Returns currenct value of paddle
uint8_t GTPDL(uint8_t index) __z88dk_fastcall;
/*
void RIGHTC() __z88dk_fastcall;
void LEFTC() __z88dk_fastcall;
void UPC() __z88dk_fastcall;
uint8_t TUPC() __z88dk_fastcall;
void DOWNC() __z88dk_fastcall;
void RDVDP() __z88dk_fastcall;
uint8_t TDOWNC() __z88dk_fastcall;
void SCALXY() __z88dk_fastcall;
*/
void MAPXY() __z88dk_fastcall;
uint16_t FETCHC_ADDR() __z88dk_fastcall;
/*
void STOREC(uint16_t addr, uint8_t mask);
void SETATR(uint8_t attr) __z88dk_fastcall;
uint8_t READC() __z88dk_fastcall;
void SETC() __z88dk_fastcall;
void NSETCX(uint16_t fillcount) __z88dk_fastcall;
*/
uint8_t RDVDP() __z88dk_fastcall;
uint8_t SNSMAT(uint8_t row) __z88dk_fastcall;
void KILBUF() __z88dk_fastcall;
@ -169,7 +198,7 @@ enum MSX1_Color {
};
// joystick positions for GTSTCK
enum GTSTCK_Direction {
typedef enum GTSTCK_Direction {
STCK_none = 0,
STCK_N,
STCK_NE,
@ -182,14 +211,14 @@ enum GTSTCK_Direction {
};
// parameter for GTSTCK
enum GTSTCK_Param {
typedef enum GTSTCK_Param {
STCK_Cursors,
STCK_Joy1,
STCK_Joy2
};
// parameter for GTTRIG
enum GTTRIG_Param {
typedef enum GTTRIG_Param {
TRIG_Spacebar,
TRIG_Joy1_A,
TRIG_Joy2_A,
@ -197,4 +226,6 @@ enum GTTRIG_Param {
TRIG_Joy2_B
};
#define VSYNC() __asm__("HALT");
#endif

View File

@ -0,0 +1,166 @@
ORG 04000H
; LOAD 04000H
; MSX cartridge header @ 0x4000 - 0x400f
dw 0x4241
dw Start
dw Start
dw 0,0,0,0,0
; ******************************
; * BIOS STANDARD ROUTINES *
; ******************************
RDSLT: EQU 000CH
CNVCHR: EQU 00ABH
MAPXYC: EQU 0111H
SETC: EQU 0120H
; ******************************
; * WORKSPACE VARIABLES *
; ******************************
FORCLR: EQU 0F3E9H
ATRBYT: EQU 0F3F2H
CGPNT: EQU 0F91FH
PATWRK: EQU 0FC40H
SCRMOD: EQU 0FCAFH
GRPACX: EQU 0FCB7H
GRPACY: EQU 0FCB9H
; ******************************
; * CONTROL CHARACTERS *
; ******************************
CR: EQU 13
Start:
GFORTY: CP 3 ; String type?
RET NZ ;
LD A,(SCRMOD) ; Mode
CP 2 ; Graphics?
RET NZ ;
EX DE,HL ; HL->Descriptor
LD B,(HL) ; B=String len
INC HL ;
LD E,(HL) ; Address LSB
INC HL ;
LD D,(HL) ; DE->String
INC B ;
GF2: DEC B ; Finished?
RET Z ;
LD A,(DE) ; A=Chr from string
CALL GPRINT ; Print it
INC DE ;
JR GF2 ; Next chr
GPRINT: PUSH AF ;
PUSH BC ;
PUSH DE ;
PUSH HL ;
PUSH IY ;
LD BC,(GRPACX) ; BC=X coord
LD DE,(GRPACY) ; DE=Y coord
CALL GDC ; Decode chr
LD (GRPACX),BC ; New X coord
LD (GRPACY),DE ; New Y coord
POP IY ;
POP HL ;
POP DE ;
POP BC ;
POP AF ;
RET ;
GDC: CALL CNVCHR ; Check graphic
RET NC ; NC=Header
JR NZ,GD2 ; NZ=Converted
CP CR ; Carriage Return?
JR Z,GCRLF ;
CP 20H ; Other control?
RET C ; Ignore
GD2: LD L,A ;
LD H,0 ; HL=Chr code
ADD HL,HL ;
ADD HL,HL ;
ADD HL,HL ; HL=Chr*8
PUSH BC ; X coord
PUSH DE ; Y coord
LD DE,(CGPNT+1) ; Character set
ADD HL,DE ; HL->Pattern
LD DE,PATWRK ; DE->Buffer
LD B,8 ; Eight byte pattern
GD3: PUSH BC ;
PUSH DE ;
LD A,(CGPNT) ; Slot ID
CALL RDSLT ; Get pattern
EI ;
POP DE ;
POP BC ;
LD (DE),A ; Put in buffer
INC DE ;
INC HL ;
DJNZ GD3 ; Next
POP DE ;
POP BC ;
LD A,(FORCLR) ; Current colour
LD (ATRBYT),A ; Set ink
LD IY,PATWRK ; IY->Patterns
PUSH DE ;
LD H,8 ; Max dot rows
GD4: BIT 7,D ; Pos Y coord?
JR NZ,GD8 ;
CALL BMDROW ; Bottom most row?
JR C,GD9 ; C=Y too large
PUSH BC ;
LD L,6 ; Max dot cols
LD A,(IY+0) ; A=Pattern row
GD5: BIT 7,B ; Pos X coord
JR NZ,GD6 ;
CALL RMDCOL ; Rightmost col?
JR C,GD7 ; C=X too large
BIT 7,A ; Pattern bit
JR Z,GD6 ; Z=0 Pixel
PUSH AF ;
PUSH DE ;
PUSH HL ;
CALL MAPXYC ; Map coords
CALL SETC ; Set pixel
POP HL ;
POP DE ;
POP AF ;
GD6: RLCA ; Shift pattern
INC BC ; X=X+1
DEC L ; Finished dot cols?
JR NZ,GD5 ;
GD7: POP BC ; Initial X coord
GD8: INC IY ; Next pattern byte
INC DE ; Y=Y+1
DEC H ; Finished dot rows?
JR NZ,GD4 ;
GD9: POP DE ; Initial Y coord
LD HL,6 ; Step
ADD HL,BC ; X=X+6
LD B,H ;
LD C,L ; BC=New X coord
CALL RMDCOL ; Rightmost col?
RET NC ;
GCRLF: LD BC,0 ; X=0
LD HL,8 ;
ADD HL,DE ;
EX DE,HL ; Y=Y+8
RET ;
BMDROW: PUSH HL ;
LD HL,191 ; Bottom dot row
OR A ;
SBC HL,DE ; Check Y coord
POP HL ;
RET ; C=Below screen
RMDCOL: PUSH HL ;
LD HL,239 ; Rightmost dot col
OR A ;
SBC HL,BC ; Check X coord
POP HL ;
RET ; C=Beyond right
END

View File

@ -0,0 +1,450 @@
ORG 04000H
; LOAD 04000H
; MSX cartridge header @ 0x4000 - 0x400f
dw 0x4241
dw Start
dw Start
dw 0,0,0,0,0
; ******************************
; * BIOS STANDARD ROUTINES *
; ******************************
RDSLT: EQU 000CH
RDVRM: EQU 004AH
WRTVRM: EQU 004AH
FILVRM: EQU 0056H
INIGRP: EQU 0072H
CHSNS: EQU 009CH
CHGET: EQU 009FH
MAPXYC: EQU 0111H
FETCHC: EQU 0114H
RSLREG: EQU 0138H
; ******************************
; * WORKSPACE VARIABLES *
; ******************************
GRPCOL: EQU 0F3D9H
FORCLR: EQU 0F3E9H
BAKCLR: EQU 0F3EAH
CGPNT: EQU 0F91FH
EXPTBL: EQU 0FCC1H
SLTTBL: EQU 0FCC5H
; ******************************
; * CONTROL CHARACTERS *
; ******************************
CR: EQU 13
RIGHT: EQU 28
LEFT: EQU 29
UP: EQU 30
DOWN: EQU 31
Start:
CHEDIT: CALL INIT ; Cold start
CH1: CALL CHRMAG ; Magnify chr
CALL CHRXY ; Chr coords
LD D,8 ; Cursor size
CALL GETKEY ; Get command
CP "Q" ; Quit
RET Z ;
LD HL,CH1 ; Set up return
PUSH HL ;
CP "A" ; Adopt
JP Z,ADOPT ;
CP CR ; Edit
JR Z,EDIT ;
LD C,1 ; C=Offset
CP RIGHT ; Right
JR Z,CH2 ;
LD C,0FFH ;
CP LEFT ; Left
JR Z,CH2 ;
LD C,0F0H ;
CP UP ; Up
JR Z,CH2 ;
LD C,16 ;
CP DOWN ; Down
RET NZ ;
CH2: LD A,(CHRNUM) ; Current chr
ADD A,C ; Add offset
LD (CHRNUM),A ; New chr
RET ;
EDIT: CALL DOTXY ; Dot coords
LD D,2 ; Cursor size
CALL GETKEY ; Get command
CP CR ; Quit
RET Z ;
LD HL,EDIT ; Set up return
PUSH HL ;
LD BC,0FE00H ; AND/OR masks
CP " " ; Space
JR Z,ED3 ;
INC C ; New OR mask
CP "." ; Dot
JR Z,ED3 ;
CP RIGHT ; Right
JR Z,ED2 ;
LD C,0FFH ; C=Offset
CP LEFT ; Left
JR Z,ED2 ;
LD C,0F8H ;
CP UP ; Up
JR Z,ED2 ;
LD C,8 ;
CP DOWN ; Down
RET NZ ;
ED2: LD A,(DOTNUM) ; Current dot
ADD A,C ; Add offset
AND 63 ; Wrap round
LD (DOTNUM),A ; New dot
RET ;
ED3: CALL PATPOS ; IY->Pattern
LD A,(DOTNUM) ; Current dot
PUSH AF ;
RRCA ;
RRCA ;
RRCA ;
AND 7 ; A=Row
LD E,A ;
LD D,0 ; DE=Row
ADD IY,DE ; IY->Row
POP AF ;
AND 7 ; A=Column
INC A ;
ED4: RRC B ; AND mask
RRC C ; OR mask
DEC A ; Count columns
JR NZ,ED4 ;
LD A,(IY+0) ; A=Pattern
AND B ; Strip old bit
OR C ; New bit
LD (IY+0),A ; New pattern
CALL CHRMAG ; Update magnified
CHROUT: CALL PATPOS ; IY->Pattern
CALL CHRXY ; Get coords
CALL MAP ; Map
LD B,8 ; Dot rows
CO1: PUSH DE ;
PUSH HL ;
LD A,8 ; Dot cols
LD E,(IY+0) ; E=Pattern
CALL SETROW ; Set row
POP HL ; HL=CLOC
POP DE ; D=CMASK
CALL DOWNP ; Down a pixel
INC IY ;
DJNZ CO1 ;
RET ;
CHRMAG: CALL PATPOS ; IY->Pattern
LD C,191 ; Start X
LD E,7 ; Start Y
CALL MAP ; Map
LD B,8 ; Dot rows
CM1: LD C,5 ; Row mag
CM2: PUSH BC ;
PUSH DE ;
PUSH HL ;
LD B,8 ; Dot columns
LD A,(IY+0) ; A=Pattern
CM3: RLCA ; Test bit
PUSH AF ;
SBC A,A ; 0=00H, 1=FFH
LD E,A ; E=Mag pattern
LD A,5 ; Column mag
CALL SETROW ; Set row
CALL RIGHTP ; Right a pixel
CALL RIGHTP ; Skip grid
POP AF ;
DJNZ CM3 ;
POP HL ; HL=CLOC
POP DE ; D=CMASK
POP BC ;
CALL DOWNP ; Down a pixel
DEC C ;
JR NZ,CM2 ;
CALL DOWNP ; Skip grid
INC IY ;
DJNZ CM1 ;
RET ;
INIT: LD BC,2048 ; Size
LD DE,CHRTAB ; Destination
LD HL,(CGPNT+1) ; Source
IN1: PUSH BC ;
PUSH DE ;
LD A,(CGPNT) ; Slot ID
CALL RDSLT ; Read chr pattern
EI ;
POP DE ;
POP BC ;
LD (DE),A ; Put in buffer
INC DE ;
INC HL ;
DEC BC ;
LD A,B ;
OR C ;
JR NZ,IN1 ;
CALL INIGRP ; SCREEN 2
LD A,(FORCLR) ; Colour 1
RLCA ;
RLCA ;
RLCA ;
RLCA ;
LD C,A ; C=Colour 1
LD A,(BAKCLR) ; Colour 0
OR C ; Mix
LD BC,6144 ; Colour table size
LD HL,(GRPCOL) ; Colour table
CALL FILVRM ; Fill colours
LD HL,177*256+11 ;
LD BC,0FFH*256+10 ;
LD E,6 ;
LD A,17 ;
CALL GRID ; Draw chr grid
LD HL,49*256+6 ;
LD BC,0AAH*256+190 ;
LD E,6 ;
LD A,9 ;
CALL GRID ; Draw mag grid
LD HL,49*256+48 ;
LD BC,0FFH*256+190 ;
LD E,6 ;
LD A,2 ;
CALL GRID ; Draw mag box
XOR A ;
LD (DOTNUM),A ; Current dot
LD HL,CHRNUM ;
LD (HL),A ; Current chr
IN2: PUSH HL ;
CALL CHROUT ; Display chr
POP HL ;
INC (HL) ; Next chr
JR NZ,IN2 ; Do 256
RET ;
GRID: PUSH AF ;
PUSH BC ;
PUSH HL ;
CALL MAP ; Map
POP BC ; B=Len,C=Step
POP AF ;
LD E,A ; E=Pattern
POP AF ; A=Count
PUSH AF ;
PUSH DE ;
PUSH HL ;
GR1: PUSH AF ;
PUSH BC ;
PUSH DE ;
PUSH HL ;
LD A,B ; A=Len
CALL SETROW ; Horizontal line
POP HL ; HL=CLOC
POP DE ; D=CMASK
GR3: CALL DOWNP ; Down a pixel
DEC C ; Done step?
JR NZ,GR3 ;
POP BC ;
POP AF ; A=Count
DEC A ; Done lines?
JR NZ,GR1 ;
POP HL ; HL=Initial CLOC
POP DE ; D=Initial CMASK
POP AF ; A=Count
GR4: PUSH AF ;
PUSH BC ;
PUSH DE ;
PUSH HL ;
GR5: LD A,1 ; Line width
CALL SETROW ; Thin line
CALL DOWNP ; Down a pixel
DJNZ GR5 ; Vertical len
POP HL ; HL=CLOC
POP DE ; D=CMASK
GR6: CALL RIGHTP ; Right a pixel
DEC C ; Done step?
JR NZ,GR6 ;
POP BC ;
POP AF ; A=Count
DEC A ; Done lines?
JR NZ,GR4 ;
RET ;
MAP: LD B,0 ; X MSB
LD D,B ; Y MSB
CALL MAPXYC ; Map coords
CALL FETCHC ; HL=CLOC
LD D,A ; D=CMASK
RET ;
RIGHTP: RRC D ; Shift CMASK
RET NC ; NC=Same cell
RP1: PUSH BC ;
LD BC,8 ; Offset
ADD HL,BC ; HL=Next cell
POP BC ;
RET ;
DOWNP: INC HL ; CLOC down
LD A,L ;
AND 7 ; Select pixel row
RET NZ ; NZ=Same cell
PUSH BC ;
LD BC,00F8H ; Offset
ADD HL,BC ; HL=Next cell
POP BC ;
RET ;
SETROW: PUSH BC ;
LD B,A ; B=Count
SE1: CALL RDVRM ; Get old pattern
SE2: LD C,A ; C=Old
LD A,D ; A=CMASK
CPL ; AND mask
AND C ; Strip old bit
RLC E ; Shift pattern
JR NC,SE3 ; NC=0 Pixel
OR D ; Set 1 Pixel
SE3: DEC B ; Finished?
JR Z,SE4 ;
RRC D ; CMASK right
JR NC,SE2 ; NC=Same cell
CALL WRTVRM ; Update cell
CALL RP1 ; Next cell
JR SE1 ; Start again
SE4: CALL WRTVRM ; Update cell
POP BC ;
RET ;
DOTXY: LD A,(DOTNUM) ; Current dot
PUSH AF ;
AND 7 ; Column
RLCA ;
LD C,A ; C=Col*2
RLCA ; A=Col*4
ADD A,C ; A=Col*6
ADD A,191 ; Grid atart
LD C,A ; C=X coord
POP AF ;
AND 38H ; Row*8
RRCA ;
LD E,A ; E=Row*4
RRCA ; A=Row*2
ADD A,E ; A=Row*6
ADD A,7 ; Grid start
LD E,A ; E=Y coord
RET ;
CHRXY: LD A,(CHRNUM) ; Current chr
PUSH AF ;
CALL MULT11 ; Column*11
ADD A,12 ; Grid start
LD C,A ; C=X coord
POP AF ;
RRCA ;
RRCA ;
RRCA ;
RRCA ;
CALL MULT11 ; Row*11
ADD A,8 ; Grid start
LD E,A ; E=Y coord
RET ;
MULT11: AND 0FH ;
LD D,A ; D=N
RLCA ;
LD B,A ; B=N*2
RLCA ;
RLCA ; A=N*8
ADD A,B ;
ADD A,D ; A=N*11
RET ;
PATPOS: LD A,(CHRNUM) ; Current chr
LD L,A ;
LD H,0 ; HL=Chr
ADD HL,HL ;
ADD HL,HL ;
ADD HL,HL ; HL=Chr*8
EX DE,HL ; DE=Chr*8
LD IY,CHRTAB ; Patterns
ADD IY,DE ; IY->Pattern
RET ;
GETKEY: LD B,0 ; Cursor flag
GE1: PUSH BC ; C=X coord
PUSH DE ; E=Y coord
CALL INVERT ; Flip cursor
POP DE ;
POP BC ;
INC B ; Flip flag
LD HL,8000 ; Blink rate
GE2: CALL CHSNS ; Check KEYBUF
JR NZ,GE3 ; NZ=Got key
DEC HL ;
LD A,H ;
OR L ;
JR NZ,GE2 ;
JR GE1 ; Time for cursor
GE3: BIT 0,B ; Cursor state
CALL NZ,INVERT ; Remove cursor
JP CHGET ; Collect character
INVERT: PUSH DE ;
CALL MAP ; Map coords
POP AF ; A=Cursor size
LD B,A ; B=Rows
LD E,A ; E=Cols
IV1: PUSH DE ;
PUSH HL ;
IV2: CALL RDVRM ; Old pattern
XOR D ; Flip a bit
CALL WRTVRM ; Put it back
CALL RIGHTP ; Right a pixel
DEC E ;
JR NZ,IV2 ;
POP HL ; HL=CLOC
POP DE ; D=CMASK
CALL DOWNP ; Down a pixel
DJNZ IV1 ;
RET ;
ADOPT: LD BC,2048 ; Size
LD DE,0EB80H ; Destination
LD (CGPNT+1),DE ;
LD HL,CHRTAB ; Source
LDIR ; Copy up high
CALL RSLREG ; Read PSLOT reg
RLCA ;
RLCA ;
AND 3 ; Select Page 3
LD C,A ;
LD B,0 ; BC=Page 3 PSLOT#
LD HL,EXPTBL ; Expanders
ADD HL,BC ;
BIT 7,(HL) ; PSLOT expanded?
JR Z,AD1 ; A=Normal
LD HL,SLTTBL ; Secondary regs
ADD HL,BC ;
LD A,(HL) ; A=Secondary reg
RLCA ;
RLCA ;
RLCA ;
RLCA ;
AND 0CH ; A=Page 3 SSLOT#
OR C ; Mix Page 3 PSLOT#
SET 7,A ; A=Slot ID
AD1: LD (CGPNT),A ;
RET ;
CHRNUM: DEFB 0 ; Current chr
DOTNUM: DEFB 0 ; Current dot
CHRTAB: DEFS 2048 ; Patterns to EAA2H
END

View File

@ -0,0 +1,59 @@
ORG 04000H
; LOAD 04000H
; MSX cartridge header @ 0x4000 - 0x400f
dw 0x4241
dw Start
dw Start
dw 0,0,0,0,0
; ******************************
; * BIOS STANDARD ROUTINES *
; ******************************
INITXT: EQU 006CH
CHPUT: EQU 00A2H
SNSMAT: EQU 0141H
BREAKX: EQU 00B7H
; ******************************
; * WORKSPACE VARIABLES *
; ******************************
INTFLG: EQU 0FC9BH
; ******************************
; * CONTROL CHARACTERS *
; ******************************
LF: EQU 10
HOME: EQU 11
CR: EQU 13
Start:
MATRIX: CALL INITXT ; SCREEN 0
MX1: LD A,HOME ;
CALL CHPUT ; Home Cursor
XOR A ; A=KBD row
MX2: PUSH AF ;
CALL SNSMAT ; Read a row
LD B,8 ; Eight cols
MX3: RLCA ; Select col
PUSH AF ;
AND 1 ;
ADD A,"0" ; Result
CALL CHPUT ; Display col
POP AF ;
DJNZ MX3 ;
LD A,CR ; Newline
CALL CHPUT ;
LD A,LF ;
CALL CHPUT ;
POP AF ; A=KBD row
INC A ; Next row
CP 11 ; Finished?
JR NZ,MX2 ;
CALL BREAKX ; CTRL-STOP
JR NC,MX1 ; Continue
XOR A ;
LD (INTFLG),A ; Clear possible STOP
RET ; Back to BASIC

256
presets/msx/siegegame.c Normal file
View File

@ -0,0 +1,256 @@
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "msxbios.h"
//#link "msxbios.c"
typedef uint8_t byte;
typedef uint16_t word;
typedef uint8_t bool;
void cursorxy(byte x, byte y) {
POSIT(y+1+(x<<8));
}
void cputcxy(byte x, byte y, char ch) {
cursorxy(x,y);
CHPUT(ch);
}
void putstring(byte x, byte y, const char* str) {
cursorxy(x,y);
while (*str) {
CHPUT(*str++);
}
}
byte getchar(byte x, byte y) {
word addr = 0x1800 | (x+1) | y*32; // TODO: use variable for base address
byte result;
result = RDVRM(addr);
//LDIRMV(&result, addr, 1);
return result;
}
void vsync() {
__asm__("HALT");
}
void delay(int x) {
while (x--) {
vsync();
}
}
#define CHAR(x) (x)
#define COLS (LINL32)
#define ROWS (LINLEN-5)
////////// GAME DATA
typedef struct {
byte x;
byte y;
byte dir;
word score;
char head_attr;
char tail_attr;
char collided:1;
char human:1;
} Player;
Player players[2];
byte credits = 0;
byte frames_per_move;
#define START_SPEED 12
#define MAX_SPEED 5
#define MAX_SCORE 7
///////////
const char BOX_CHARS[8] = {
CHAR('+'), CHAR('+'), CHAR('+'), CHAR('+'),
CHAR('-'), CHAR('-'), CHAR('!'), CHAR('!') };
void draw_box(byte x, byte y, byte x2, byte y2, const char* chars) {
byte x1 = x;
cputcxy(x, y, chars[2]);
cputcxy(x2, y, chars[3]);
cputcxy(x, y2, chars[0]);
cputcxy(x2, y2, chars[1]);
while (++x < x2) {
cputcxy(x, y, chars[5]);
cputcxy(x, y2, chars[4]);
}
while (++y < y2) {
cputcxy(x1, y, chars[6]);
cputcxy(x2, y, chars[7]);
}
}
void draw_playfield() {
draw_box(0,1,COLS-1,ROWS-1,BOX_CHARS);
putstring(0,0,"Plyr1:");
putstring(20,0,"Plyr2:");
cputcxy(7,0,CHAR(players[0].score+'0'));
cputcxy(27,0,CHAR(players[1].score+'0'));
}
typedef enum { D_RIGHT, D_DOWN, D_LEFT, D_UP } dir_t;
const char DIR_X[4] = { 1, 0, -1, 0 };
const char DIR_Y[4] = { 0, 1, 0, -1 };
void init_game() {
memset(players, 0, sizeof(players));
players[0].head_attr = CHAR('1');
players[1].head_attr = CHAR('2');
players[0].tail_attr = CHAR('@');
players[1].tail_attr = CHAR('%');
frames_per_move = START_SPEED;
}
void reset_players() {
players[0].x = players[0].y = 5;
players[0].dir = D_RIGHT;
players[1].x = 25;
players[1].y = 19;
players[1].dir = D_LEFT;
players[0].collided = players[1].collided = 0;
}
void draw_player(Player* p) {
cputcxy(p->x, p->y, p->head_attr);
}
void move_player(Player* p) {
cputcxy(p->x, p->y, p->tail_attr);
p->x += DIR_X[p->dir];
p->y += DIR_Y[p->dir];
if (getchar(p->x, p->y) != CHAR(' '))
p->collided = 1;
draw_player(p);
}
void human_control(Player* p) {
byte dir = 0xff;
byte joystick = GTSTCK(STCK_Joy1);
if (!p->human) return;
if (joystick == STCK_W) dir = D_LEFT;
if (joystick == STCK_E) dir = D_RIGHT;
if (joystick == STCK_N) dir = D_UP;
if (joystick == STCK_S) dir = D_DOWN;
// don't let the player reverse
if (dir < 0x80 && dir != (p->dir ^ 2)) {
p->dir = dir;
}
}
byte ai_try_dir(Player* p, dir_t dir, byte shift) {
byte x,y;
dir &= 3;
x = p->x + (DIR_X[dir] << shift);
y = p->y + (DIR_Y[dir] << shift);
if (x < 29 && y < 27 && getchar(x, y) == CHAR(' ')) {
p->dir = dir;
return 1;
} else {
return 0;
}
}
void ai_control(Player* p) {
dir_t dir;
if (p->human) return;
dir = p->dir;
if (!ai_try_dir(p, dir, 0)) {
ai_try_dir(p, dir+1, 0);
ai_try_dir(p, dir-1, 0);
} else {
ai_try_dir(p, dir-1, 0) && ai_try_dir(p, dir-1, 1+(rand() & 3));
ai_try_dir(p, dir+1, 0) && ai_try_dir(p, dir+1, 1+(rand() & 3));
ai_try_dir(p, dir, rand() & 3);
}
}
byte gameover;
void flash_colliders() {
byte i;
// flash players that collided
for (i=0; i<56; i++) {
//cv_set_frequency(CV_SOUNDCHANNEL_0, 1000+i*8);
//cv_set_attenuation(CV_SOUNDCHANNEL_0, i/2);
if (players[0].collided) players[0].head_attr ^= 0x80;
if (players[1].collided) players[1].head_attr ^= 0x80;
delay(2);
draw_player(&players[0]);
draw_player(&players[1]);
}
//cv_set_attenuation(CV_SOUNDCHANNEL_0, 28);
}
void make_move() {
byte i;
for (i=0; i<frames_per_move; i++) {
human_control(&players[0]);
delay(1);
}
ai_control(&players[0]);
ai_control(&players[1]);
// if players collide, 2nd player gets the point
move_player(&players[1]);
move_player(&players[0]);
}
void play_game();
void declare_winner(byte winner) {
byte i;
CLS();
for (i=0; i<ROWS/2-3; i++) {
draw_box(i,i,COLS-1-i,ROWS-1-i,BOX_CHARS);
delay(1);
}
putstring(12,10,"WINNER:");
putstring(12,13,"PLAYER ");
cputcxy(12+7, 13, CHAR('1')+winner);
delay(75);
gameover = 1;
}
void play_round() {
reset_players();
CLS();
draw_playfield();
while (1) {
make_move();
if (players[0].collided || players[1].collided) break;
}
flash_colliders();
// add scores to players that didn't collide
if (players[0].collided) players[1].score++;
if (players[1].collided) players[0].score++;
// increase speed
if (frames_per_move > MAX_SPEED) frames_per_move--;
// game over?
if (players[0].score != players[1].score) {
if (players[0].score >= MAX_SCORE)
declare_winner(0);
else if (players[1].score >= MAX_SCORE)
declare_winner(1);
}
}
void play_game() {
gameover = 0;
init_game();
players[0].human = 1;
while (!gameover) {
play_round();
}
}
void main() {
INIT32();
play_game();
}

View File

@ -15,6 +15,9 @@ import { TMS9918A } from "../video/tms9918a";
var MSX_PRESETS = [
{id:'helloworld.asm', name:'Hello World (ASM)'},
{id:'redbook_kbd.asm', name:'Redbook Keyboard Scanner (ASM)'},
{id:'siegegame.c', name:'Siege Game'},
{id:'eliza.c', name:'Eliza'},
];
var MSX_KEYCODE_MAP = makeKeycodeMap([

View File

@ -86,7 +86,8 @@ inline void cvu_set_sprite(const cv_vmemp base, uint_fast8_t number, const struc
// Write sprite to display memory (in mode 4). Use the location of the sprite table as base. number should be in [0, 63].
#ifdef CV_SMS
inline void cvu_set_sprite4(const cv_vmemp base, uint_fast8_t number, const struct cvu_sprite4 *sprite)
// TODO: sdcc doesn't like inline here
void cvu_set_sprite4(const cv_vmemp base, uint_fast8_t number, const struct cvu_sprite4 *sprite)
{
cvu_voutb(sprite->y, base + number);
cv_set_write_vram_address(base + 0x80 + number * 2);

View File

@ -86,7 +86,8 @@ inline void cvu_set_sprite(const cv_vmemp base, uint_fast8_t number, const struc
// Write sprite to display memory (in mode 4). Use the location of the sprite table as base. number should be in [0, 63].
#ifdef CV_SMS
inline void cvu_set_sprite4(const cv_vmemp base, uint_fast8_t number, const struct cvu_sprite4 *sprite)
// TODO: sdcc doesn't like inline here
void cvu_set_sprite4(const cv_vmemp base, uint_fast8_t number, const struct cvu_sprite4 *sprite)
{
cvu_voutb(sprite->y, base + number);
cv_set_write_vram_address(base + 0x80 + number * 2);