NEO GEO Japanese Traditional Script

Made something in Assembly? Show it off, and tell us how it works...
Absolute beginners welcome... we want to see what you've done!
Forum rules
There is a special rule on this forum...
This forum is intended to offer equal amounts encouragement and constructive feedback...
Therefore, if you say 2 negative things about someones work, you must think of 2 or more equally positive things...

Eg: "Great first effort, the idea is absolutely fascinating... However I noticed a few bugs, and maybe the graphics could be improved..."

If you can't think of anything good to say, then don't say anything!

If we don't encourage newbie programmers they won't have the confidence and motivation to stick at it and become great programmers! *speaking from experience*
Post Reply
puppydrum64
Posts: 26
Joined: Thu Apr 22, 2021 9:30 pm

NEO GEO Japanese Traditional Script

Post by puppydrum64 » Fri Jun 18, 2021 4:48 pm

I'm trying to make a ninja game for the Neo Geo so I thought it would be cool if the intro cutscene had a letter written in traditional Japanese style (writing top to bottom, right to left.) The NEOGEO has a built-in Japanese font that makes this pretty easy.
konnichiwa_sekai.PNG
konnichiwa_sekai.PNG (79.83 KiB) Viewed 241 times
The source code for this looks like absolute spaghetti, it's difficult to follow and I plan on cleaning that up. I'm sure there are improvements to the structure that I could make.

To use this, all you have to do is copy this source code into its own file, use an include directive with its filename, and then in your main program call "JSR JapaneseScript" and it will do the rest. Updating this to have variable input is easy. Create your desired string in the format described in the code example, load its effective address into A0, then call the subroutine.

This code supports the following features:
* All hiragana characters, including the small versions, and both types of accent marks.
* Periods and commas (quotation marks not implemented yet)
* Automatically moves to the next line if you reach the bottom of the screen. There is currently no error checking for going off the left side of the screen, you have been warned!
* Katakana and kanji are not implemented yet.

Feedback is greatly appreciated. This code is functional but it could be formatted better, so any tips on how to improve readability are greatly appreciated.

Code: Select all

JapaneseScript:
	pushall
	; GOAL: WRITE A SYLLABLE, MOVE VRAM TO THE RIGHT OF IT, WRITE MODIFIER (IF ANY), MOVE DOWN, REPEAT.
	; SMALL HIRAGANA GET WRITTEN BELOW A PARENT SYLLABLE.
	; ACCENT MARKS GET WRITTEN TO THE RIGHT OF A SYLLABLE.
	
	;PREP WORK
	ClearDataRegs
	
	; D0 = INDEX OF THE CHARACTER WE ARE WRITING TO SCREEN.
	; D1 = VRAM ADDRESS
	; D2 = THE ACTUAL TILE ADDRESS IN 202.S1 OF THE CHOSEN CHARACTER.
	; D3 = SHADOW VRAM ADDRESS USED AS A COMPARATOR FOR REACHING END OF LINE.
	
	
	;LOAD DATA BLOCK ADDRESSES
	LEA TestStringJapanese,A0				;LOAD THE MESSAGE WE WANT TO TYPE
	LEA HIRAGANA_LIST,A1					;LOAD HIRAGANA TABLE
	
	;PREP VRAM
	CLR.W D2								;RESET D2 FROM THE LAST ITERATION OF THE LOOP.
	MOVE.W #FIX_TOPRIGHT-32,D1
	
	MOVE.W #1,$3C0004						;SET INCREMENT FACTOR
	
loop_PrintStringJapanese:
	MOVE.W D1,$3C0000						;LOAD STARTING ADDRESS FOR VRAM WRITING
	MOVE.B (A0)+,D0							;GET INDEX OF NEXT CHARACTER TO PRINT
	CMP.B #$FF,D0							;DID WE REACH THE TERMINATOR BYTE?
	BEQ EndOfStringJapanese
	LSL.B #2,D0								;WE ARE INDEXING INTO A TABLE OF LONGS SO MULTIPLY BY 4
	
	;OUR MODIFIERS START AT $BC.
	CMP.B #$E0,D0
	BCC PrintAccentMark						;WE NEED TO PRINT AN ACCENT MARK NOW.

	MOVE.L (0,A1,D0),A2						;GET EFFECTIVE ADDRESS OF THE DESIRED SYLLABLE.

	MOVE.W (A2),D2							;STORE ITS INDEX FROM 202.S1 INTO D2
	ADD.W #$3000,D2							;ADD PALETTE NUMBER.
	MOVE.W D2,$3C0002						;WRITE IT TO THE FIX LAYER. VRAMADDR AUTO INCREMENTS DOWNWARD.
	
	CMP.B #0,D0								;IS THIS THE DUMMY CHARACTER? IF SO DO NOT ADD $100 TO IT.
	BEQ	noSecondHalf
	ADD.W #$100,D2							;WE JUST WROTE THE TOP HALF. THE BOTTOM HALF IS ALWAYS $100 TILES AWAY.
noSecondHalf:
	MOVE.W D2,$3C0002						;WRITE THE BOTTOM HALF TO THE FIX LAYER.
	ADDQ.W #2,D1							;ADD 2 TO VRAM ADDRESS.
	MOVE.W D1,D3							;COPY D1 TO D3 TO USE AS BOUNDS CHECKER.
	AND.B #$1E,D3
	CMP.B #$1E,D3							;ARE WE AT THE BOTTOM OF THE VISIBLE FIX LAYER?
	BEQ NewLineJapanese
	BRA loop_PrintStringJapanese
EndOfStringJapanese:
	Debug
	popall
	rts
	
NewLineJapanese:
	SUB.W #$1D,D1
	SUB.W #$60,D1
	
	;TODO: ADD BOUNDS CHECKING FOR GOING OFF THE LEFT SIDE.
	
	BRA loop_PrintStringJapanese

PrintAccentMark:
	ADD.W #$001E,D1							;SET VRAM ADDRESS TO THE RIGHT SIDE OF THE CHARACTER WE JUST WROTE.
	MOVE.W D1,$3C0000
	MOVE.L (0,A1,D0),A2						;GET EFFECTIVE ADDRESS OF THE DESIRED SYLLABLE.

	MOVE.W (A2),D2							;STORE ITS INDEX FROM 202.S1 INTO D2
	
	ADD.W #$3000,D2							;ADD PALETTE NUMBER.
	MOVE.W D2,$3C0002						;WRITE IT TO THE FIX LAYER. VRAMADDR AUTO INCREMENTS DOWNWARD.
	
	ADD.W #$0100,D2							;ADD $100 TO GET TO BOTTOM HALF OF THIS.
	MOVE.W D2,$3C0002
	SUB.W #$001E,D1							;CHANGE VRAMADDR BACK TO WHERE WE WERE AS IF NOTHING HAPPENED.
	BRA loop_PrintStringJapanese
	
	;THIS WORKS FOR DAKUTEN, MARU, COMMA, AND PERIOD.
	
	;BUG: BLACK BAR LIKE ON THE OVERSCAN APPEARS AFTER THE END OF THE CHARACTER.
	; CMP.B #46,D0
	; BLT DONTADDMODIFIER			;THIS PART IS NOT NEEDED SINCE THESE GET WRITTEN JUST LIKE NORMAL SYLLABLES.
	
	;CMP.B #55,D0
	;BGT ACCENTMARK

	
TestStringJapanese:
	DC.B 10,56,46,22,17,26,0,14,6,2,59,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,255
	EVEN
	
; USAGE:
; THE CHARACTER'S INDEX IN THE TABLE "HIRAGANA_LIST" IS WHAT IS READ FROM THE STRING. THIS SAVES A TON OF DATA OVER TIME.
; ACCENT MARKS ARE TREATED AS THEIR OWN CHARACTER. IT WILL GET WRITTEN AUTOMATICALLY IN THE RIGHT PLACE. PUT THEM AFTER THE CHARACTER YOU WANT TO MODIFY.
; EXAMPLE: KO = 10. GO = 10,56
; THERE IS NO ERROR CHECKING FOR SYLLABLES THAT DON'T USE ACCENT MARKS. IT IS UP TO YOU TO USE THEM CORRECTLY!
; COMMAS AND PERIODS NOT IMPLEMENTED YET.
	
	
;CHARACTER CHART: TOP HALF, BOTTOM HALF

;HIRAGANA	(BOTTOM HALF = TOP HALF + $0100)

HIRAGANA_LIST:
	DC.L DUMMY_HIRAGANA		;0
	
	DC.L A_HIRAGANA   		;1
	DC.L I_HIRAGANA   		;2
	DC.L U_HIRAGANA   		;3
	DC.L E_HIRAGANA   		;4
	DC.L O_HIRAGANA   		;5

	DC.L KA_HIRAGANA 	 	;6
	DC.L KI_HIRAGANA 	 	;7
	DC.L KU_HIRAGANA 	 	;8
	DC.L KE_HIRAGANA 	 	;9
	DC.L KO_HIRAGANA 	 	;10

	DC.L SA_HIRAGANA 	 	;11
	DC.L SHI_HIRAGANA 	 	;12
	DC.L SU_HIRAGANA 	 	;13
	DC.L SE_HIRAGANA 	 	;14
	DC.L SO_HIRAGANA 	 	;15

	DC.L TA_HIRAGANA	 	;16
	DC.L CHI_HIRAGANA 	 	;17
	DC.L TSU_HIRAGANA	 	;18
	DC.L TE_HIRAGANA	 	;19
	DC.L TO_HIRAGANA	 	;20

	DC.L NA_HIRAGANA		;21 
	DC.L NI_HIRAGANA	 	;22
	DC.L NU_HIRAGANA	 	;23
	DC.L NE_HIRAGANA	 	;24
	DC.L NO_HIRAGANA	 	;25

	DC.L HA_HIRAGANA	 	;26
	DC.L HI_HIRAGANA	 	;27
	DC.L FU_HIRAGANA	 	;28
	DC.L HE_HIRAGANA	 	;29
	DC.L HO_HIRAGANA	 	;30

	DC.L MA_HIRAGANA	 	;31
	DC.L MI_HIRAGANA	 	;32
	DC.L MU_HIRAGANA	 	;33
	DC.L ME_HIRAGANA	 	;34
	DC.L MO_HIRAGANA	 	;35

	DC.L YA_HIRAGANA	 	;36
	DC.L YU_HIRAGANA	 	;37
	DC.L YO_HIRAGANA		;38
		
	DC.L RA_HIRAGANA		;39
	DC.L RI_HIRAGANA		;40
	DC.L RU_HIRAGANA		;41
	DC.L RE_HIRAGANA	 	;42
	DC.L RO_HIRAGANA	 	;43

	DC.L WA_HIRAGANA	 	;44
	DC.L WO_HIRAGANA	 	;45
	DC.L N_HIRAGANA		 	;46
	
	;DECIMAL 0 THRU DECIMAL 46 ARE FULL-SIZE SYLLABLES AND CAN STAND ALONE.
	
	;TREAT THESE AS "OPCODES" THAT MODIFY THE SYLLABLE BEFORE IT.
	;THESE ARE WRITTEN BELOW THE SYLLABLE. NOTHING IS WRITTEN TO THE RIGHT OF THEM.
	DC.L SMALL_A_HIRAGANA	;47
	DC.L SMALL_I_HIRAGANA	;48
	DC.L SMALL_U_HIRAGANA	;49
	DC.L SMALL_E_HIRAGANA	;50
	DC.L SMALL_O_HIRAGANA	;51

	DC.L SMALL_YA_HIRAGANA	;52
	DC.L SMALL_YU_HIRAGANA	;53
	DC.L SMALL_YO_HIRAGANA	;54
	DC.L SMALL_TSU_HIRAGANA	;55 (TECHNICALLY THIS MODIFIES THE SYMBOL AFTER IT BUT THE COMPUTER DOESN'T SEE IT DIFFERENTLY.)

	;THESE ARE WRITTEN TO THE RIGHT OF THE SYLLABLE.
	DC.L DAKUTEN			;56
	DC.L MARU				;57
	DC.L JP_COMMA			;58
	DC.L JP_PERIOD			;59
	
DUMMY_HIRAGANA: DC.W $0000		;PLACEHOLDER FOR CHARACTERS THAT DO NOT USE MODIFIERS

A_HIRAGANA:  DC.W $0180
I_HIRAGANA:  DC.W $0181
U_HIRAGANA:  DC.W $0182
E_HIRAGANA:  DC.W $0183
O_HIRAGANA:  DC.W $0184

KA_HIRAGANA: 	DC.W $0185
KI_HIRAGANA: 	DC.W $0186
KU_HIRAGANA: 	DC.W $0187
KE_HIRAGANA: 	DC.W $0188
KO_HIRAGANA: 	DC.W $0189

SA_HIRAGANA: 	DC.W $018A
SHI_HIRAGANA: 	DC.W $018B
SU_HIRAGANA: 	DC.W $018C
SE_HIRAGANA: 	DC.W $018D
SO_HIRAGANA: 	DC.W $018E

TA_HIRAGANA:	DC.W $018F
CHI_HIRAGANA: 	DC.W $0190
TSU_HIRAGANA:	DC.W $0191
TE_HIRAGANA:	DC.W $0192
TO_HIRAGANA:	DC.W $0193

NA_HIRAGANA:	DC.W $0194
NI_HIRAGANA:	DC.W $0195
NU_HIRAGANA:	DC.W $0196
NE_HIRAGANA:	DC.W $0197
NO_HIRAGANA:	DC.W $0198

HA_HIRAGANA:	DC.W $0199
HI_HIRAGANA:	DC.W $019A
FU_HIRAGANA:	DC.W $019B
HE_HIRAGANA:	DC.W $019C
HO_HIRAGANA:	DC.W $019D

MA_HIRAGANA:	DC.W $019E
MI_HIRAGANA:	DC.W $019F
MU_HIRAGANA:	DC.W $01A0
ME_HIRAGANA:	DC.W $01A1
MO_HIRAGANA:	DC.W $01A2

YA_HIRAGANA:	DC.W $01A3
YU_HIRAGANA:	DC.W $01A4
YO_HIRAGANA:	DC.W $01A5

RA_HIRAGANA:	DC.W $01A6
RI_HIRAGANA:	DC.W $01A7
RU_HIRAGANA:	DC.W $01A8
RE_HIRAGANA:	DC.W $01A9
RO_HIRAGANA:	DC.W $01AA

WA_HIRAGANA:	DC.W $01AB
WO_HIRAGANA:	DC.W $01AC
N_HIRAGANA:		DC.W $01AD

SMALL_A_HIRAGANA: DC.W $01AE
SMALL_I_HIRAGANA: DC.W $01AF
SMALL_U_HIRAGANA: DC.W $01B0
SMALL_E_HIRAGANA: DC.W $01B1
SMALL_O_HIRAGANA: DC.W $01B2

SMALL_YA_HIRAGANA: DC.W $01B3
SMALL_YU_HIRAGANA: DC.W $01B4
SMALL_YO_HIRAGANA: DC.W $01B5
SMALL_TSU_HIRAGANA: DC.W $01B6

DAKUTEN:			DC.W $01B7
MARU:				DC.W $01B8
JP_LEFT_QUOTE:		DC.W $01B9
JP_RIGHT_QUOTE:	DC.W $01BA
JP_COMMA:			DC.W $01FA
JP_PERIOD:			DC.W $01FB

Post Reply

Return to “Show and Tell”